home *** CD-ROM | disk | FTP | other *** search
/ stazsoftware.com / www.stazsoftware.com.tar / www.stazsoftware.com / futurebasic / sample-code / DBFD.sit / DBFD2.0 / DataBrowser With Toolbox / BasicDataBrowser 1.1.bas < prev    next >
BASIC Source File  |  2005-01-16  |  80KB  |  2,292 lines

  1.  
  2. '~'A
  3. '                       Runtime : Rntm Appearance.Incl
  4. '                           CPU : Carbon
  5. '                    CALL Req'd : Off
  6. '~'B
  7. /*
  8.      DataBrowser demo (experimental). Version 1.0 beta
  9.  
  10.      Freely adaptated from the original C code by Apple, this little demo
  11.      is intended to illustrate the strength of the DataBrowser Carbon control
  12.      that sports impressive features.
  13.  
  14.           Ñ No limitation on the number of cells displayed in a list,
  15.           Ñ Built-in drag-and-drop handling,
  16.           Ñ Built-in display types for text, icons, checkboxes, pop-up menus,
  17.             progress bars, relevance ranks, and sliders,
  18.           Ñ Support for contextual menus and context-sensitive help,
  19.           Ñ Built-in text editing for cells displaying text, and
  20.           Ñ Built-in hierarchical list support.
  21.  
  22. CREATING A DATABROWER
  23. '~'9
  24.      A DataBrowser is really a control that you create and install in a window,
  25.      however there is a specific Toolbox function for that purpose, namely
  26.      CreateDataBrowserControl.
  27.  
  28. INSTALLING CALLBACK PROCEDURES
  29. '~'9
  30.      This particular control communicates with your application via a set of
  31.      callback procedures that you must install calling InitDataBrowserCallbacks
  32.      after you have filled the appropriate fields of a particular structure.
  33.  
  34.      Only one of these procedures is required: itemDataCallback which is called
  35.      when the DataBrowser asks your program for the actual data it must display.
  36.      The other optional callback procedures deal with the Drag & Drop,
  37.      Carbon Help tags and Contextual menu features. There are also two additional
  38.      callback procedures, one is itemNotificationCallback which is called
  39.      when interesting conditions happen during the interaction of the end user
  40.      with the DataBrowser, the other, itemCompareCallback, lets you define a 
  41.      specific method for sorting items that the DataBrowser can't handle automatically.
  42.  
  43.      If you need more customization you can install extra callback procedures
  44.      with InitDataBrowserCustomCallbacks (passing to it another specific structure
  45.      whose fields include drawItemCallback, editTextCallback, hitTestCallback, etc.)
  46.      Read the Apple documentation for more info.
  47.  
  48. CONFIGURING THE DATABROWSER (adding columns)
  49. '~'9
  50.      Once you have installed your callback routines, you must configure
  51.      the DataBrowser. Basically, it consists in defining each column. This is done
  52.      with, again, a structure called DataBrowserListViewColumnDesc that describes
  53.      various properties shared by the items in that column. The stucture has two
  54.      fields (propertyDesc and headerBtnDesc) that are also records. All the fields
  55.      of the whole record must be explicitely set. Here is the complete set:
  56.  
  57.           DIM columnDescriptor AS DataBrowserListViewColumnDesc
  58.  
  59.           columnDescriptor.propertyDesc.DataBrowserPropertyID
  60.           columnDescriptor.propertyDesc.DataBrowserPropertyType
  61.           columnDescriptor.propertyDesc.DataBrowserPropertyFlags
  62.  
  63.           columnDescriptor.headerBtnDesc.version
  64.           columnDescriptor.headerBtnDesc.minimumWidth
  65.           columnDescriptor.headerBtnDesc.maximumWidth
  66.           columnDescriptor.headerBtnDesc.titleOffset
  67.           columnDescriptor.headerBtnDesc.titleString
  68.           columnDescriptor.headerBtnDesc.initialOrder
  69.           columnDescriptor.headerBtnDesc.btnFontStyle   (<=== ControlFontStyleRec )
  70.           columnDescriptor.headerBtnDesc.btnContentInfo (<=== ControlButtonContentInfo )
  71.  
  72.      Note that the DataBrowserPropertyID is a number that identifies the column; you
  73.      can think of it as a button ID. You may simply define a constant that would ease
  74.      the reading of your code later, for example:
  75.  
  76.      _columnName = _"name"
  77.      _columnTel  = _"phon"
  78.      and so on...
  79.  
  80.      Then you can add the column in the DataBrowser with AddDataBrowserListViewColumn
  81.      and repeat the operation for the next column. And that's it. Well almost...
  82.  
  83. ADDING ITEMS TO THE LIST (adding rows)
  84. '~'9
  85.      You must supply then the data to display. Here in the demo, we have a notification
  86.      callback procedure that will be invoked when the DataBrowser is opened,
  87.      so we will take that opportunity to fill in the browser with data. You must keep
  88.      in mind that the data you provide at this time are not the actual data that your
  89.      program maintains but they are numbers, each one uniquely identifying an item.
  90.      The DataBrowser maintains that list of identifiers and will ask your program later
  91.      to provide the information it must display for each item (i.e. when the itemDataCallback
  92.      procedure is called.)
  93.      
  94.      Adding identifiers is like adding rows in a table and it is done with:
  95.  
  96.      AddDataBrowserItems( browser, container, numItems, itemsPtr, preSort )
  97.      
  98.      browser   is the DataBrowser ControlRef
  99.      container may be set to an existing itemID, in this case, the items added are
  100.                subItems and the list is a hierarchical list.
  101.      numItems  is the number of items you want to add at once
  102.      itemsPtr  is a pointer to the identifiers you want to add (it can be the address
  103.                of an array of identifiers).
  104.      preSort   tells the DataBrowser if the new items are already sorted or not.
  105.  
  106. DISPLAYING THE INFO
  107. '~'9
  108.      Now that you have columns and rows, you can display each cell in the table.
  109.      When the DataBrowser control needs to update the display, it calls your
  110.      application via the itemDataCallback routine. It is to note that the same routine
  111.      is invoked both for getting and setting the data of the cells. The DataBrowser
  112.      can inform your program when the end user has changed a cell's content. If you
  113.      accept the change, your program must synchronize internally its own data so that
  114.      the next time the DataBrowser calls the routine to update the display the right
  115.      information is passed back. This is not shown in the current demo that merely
  116.      provides info to the DataBrowser for the display only.
  117.  
  118.      The itemDataCallback procedure (also known as GetSetItemDataProc) receives
  119.      the following parameters: 
  120.  
  121.      GetSetItemDataProc( browser , itemID, propertyID, itemData, changeValue)
  122.  
  123.      browser     is the DataBrowser ControlRef
  124.      itemID      is the item identifier (the row in the table)
  125.      property    is the column identifier
  126.      itemData    is a pointer to a buffer that contains or will receive the data
  127.      changeValue is a boolean value. If that parameter is true, that means that
  128.                  the cell's content has been changed by the end user, and you
  129.                  can retrieve the new value in the itemData buffer. You must then
  130.                  update the info that your program maintains internally. If changeValue
  131.                  is false, you are asked to pass the value in the itemData buffer
  132.                  so that the DataBrowser can display the correct information to the
  133.                  end user.
  134.  
  135.      The value stored or retrieved via the itemData buffer depends on the column's type.
  136.      Note that each type has its own Toolbox getter and setter functions, for example:
  137.      SetDataBrowserItemDataText, GetDataBrowserItemDataIcon, SetDataBrowserItemDataBooleanValue
  138.  
  139.      In this demo there are two dialog windows that allow you to change some other settings of
  140.      the DataBrowser. Toying a bit with the program, you will be impressed by that
  141.      incredible control (try to drag the column headers, or to play with the keyboard for instance)
  142.  
  143.  ADDITIONAL NOTE 
  144. '~'9
  145.      This is the basis to start, but there's much more to learn about this versatile control.
  146.      You should read Apple Technote 2009 for more in depth information.
  147.  
  148.      The DataBrowser is somewhat intimidating at first glance, but once you have understood
  149.      the principles, all becomes easier. The demo wants to showcase the main features,
  150.      but there is much more to learn and discover on that powerful control.
  151.  
  152.      The known bugs:
  153.  
  154.      Ñ the column checkbox behaves strangely
  155.  
  156.      Ñ the application crash on closing the main window via the Close menu item
  157.      has been fixed thanks to Robert Purves.
  158.  
  159.      I have also improved a bit the original demo from Apple, but I have also
  160.      cluttered slightly the code because I wanted to use prototype functions
  161.      with all the callback procedures defined in this program.
  162.  
  163.                                                                  Alain   April 2003
  164. */
  165. '~'6
  166.  
  167. resources "Basic DataBrower.rsrc"
  168.  
  169. include "Tlbx DragMgr.Incl"// used for declarations for drag&drop support
  170. include "Tlbx MacHelp.Incl"// used for help tags support ?
  171. include "Tlbx CarbonEvents.Incl"// original FB header for Carbon Events
  172.  
  173. include "Tlbx ControlDefinitions.Incl"// my converted Apple header file for data browser declaration
  174.  
  175. '~Toolbox Added Declarations
  176.  
  177. #define DialogItemIndex       as SInt16
  178. #define ClickActivationResult as UInt32
  179.  
  180. begin record hlRec
  181. dim lHigh as UInt32
  182. dim lLow  as UInt32
  183. end record
  184.  
  185. begin record LongDateCvt
  186. begin union
  187. dim c.64 'as  SInt64 
  188. dim hl as hlRec
  189. end union
  190. end record
  191.  
  192. _kWindowInWindowMenuAttribute  = (1 << 27 )
  193. _kControlDataBrowserPart       = 24
  194. _typeUInt32 = _"magn"
  195. _kControlNoContent = 0
  196. _normal = 0
  197.  
  198. _kControlFontViewSystemFont    = -4 /* force to views system font (DataBrowser control only)*/
  199.  
  200. toolbox fn SetAutomaticControlDragTrackingEnabledForWindow( WindowRef inWindow, Boolean inTracks) = OSStatus
  201. toolbox fn GetDialogWindow(DialogRef dialog) = WindowRef
  202. toolbox fn SetControlProperty ( ControlRef c, OSType propertyCreator, OSType propertyTag, UInt32 propertySize, ptr * propertyData ) = OSStatus
  203. toolbox fn GetControlProperty ( ControlRef c, OSType propertyCreator, OSType propertyTag, UInt32 bufferSize, UInt32 * actualSize, ptr * propertyBuffer ) = OSStatus
  204. toolbox fn GetControlPropertySize ( ControlRef c, OSType propertyCreator, OSType propertyTag, UInt32 * size ) = OSStatus
  205. toolbox fn RemoveControlProperty ( ControlRef c, OSType propertyCreator, OSType propertyTag ) = OSStatus
  206. toolbox fn SetWindowClass(WindowRef,WindowClass) = OSStatus
  207. toolbox fn GetDialogFromWindow(WindowRef window) = DialogRef
  208. toolbox fn CFAllocatorGetDefault = CFAllocatorRef
  209. toolbox fn GetControlClickActivation( ControlRef inControl, Point inWhere, EventModifiers inModifiers, ClickActivationResult * outResult) = OSStatus
  210. toolbox fn CompareString( str255 aStr, str255 bStr, Handle itl2Handle) = short
  211.  
  212. '~Application Constants
  213.  
  214. begin enum
  215. _folderIndex
  216. _documentIndex
  217. _folderAliasIndex
  218.  
  219. _totalNumIcons
  220.  
  221. _settingsDLOGResID   = 130
  222. _customizeDLOGResID  = 129
  223.  
  224. _contextualMenuResID = 200
  225. end enum
  226.  
  227. begin enum 2
  228. _noDisjointBtn
  229. _dragSelectBtn
  230. _alwaysExtendBtn
  231. _selectOnlyOneBtn
  232. _resetSelectionBtn
  233. _commandTogglesBtn
  234.  
  235. _activeItemsBtn
  236. _frameAndFocusBtn
  237. _verticalScrollBtn
  238. _horizontalScrollBtn
  239.  
  240. _noEmptySelectionBtn
  241. end enum
  242.  
  243. begin enum 1
  244. _disclosureBtn
  245. _varHeightRowsBtn
  246. _expandableRowsBtn
  247.  
  248. _plainBackgroundBtn
  249. _fillHiliteStyleBtn
  250. _useRelativesDatesBtn
  251. _showHeaderButtonsBtn
  252. end enum
  253.  
  254. begin enum
  255. _closeWindowCmd         = _"clos"
  256.  
  257. _DataBrowserSettingsCmd = _"stng"
  258. _customizeViewCmd       = _"cust"
  259. _showPlacardCmd         = _"plac"
  260.  
  261. _showFrameCmd           = _"fram"
  262. _revealItemCmd          = _"show"
  263. _selectionFlagsCmd      = _"flag"
  264. end enum
  265.  
  266. begin enum
  267. _itemsPerContainer  = 10
  268.  
  269. _myCreator          = _"DEMO"
  270. _myDataBrowser      = _"Brsr"
  271. _myEventHandler     = _"Evnt"
  272. _myCustomizerID     = _" ID "
  273.  
  274. _checkboxColumnID   = _"cbox"
  275. _flavorColumnID     = _"flvr"
  276. _colorColumnID      = _"colr"
  277. _indexColumnID      = _"indx"
  278. _itemIDColumnID     = _"item"
  279. _iconOnlyColumnID   = _"icon"
  280. _dateTimeColumnID   = _"date"
  281. _popupMenuColumnID  = _"menu"
  282. _progressColumnID   = _"pbar"
  283. _sliderColumnID     = _"sldr"
  284. end enum
  285.  
  286. begin enum
  287. _btnHeight      = 20
  288. _btnWidth       = 60
  289. _scrollBarWidth = 16
  290. end enum
  291.  
  292. '~Application Globals
  293.  
  294. begin globals
  295.  
  296. dim &&
  297. dim as MenuRef                      gContextualMenu
  298. dim as ControlRef                   gPlacard
  299. dim as IconRef                      gIcon(_totalNumIcons)
  300. dim as DataBrowserTableViewColumnID gCols(9)
  301.  
  302. dim as proc                         gPlacardDrawProc         
  303.  
  304. dim as proc                         gAcceptDragProc          
  305. dim as proc                         gReceiveDragProc         
  306. dim as proc                         gAddDragItemProc         
  307. dim as proc                         gGetSetItemDataProc      
  308. dim as proc                         gItemComparisonProc      
  309. dim as proc                         gItemNotificationProc    
  310. dim as proc                         gItemHelpContentProc     
  311. dim as proc                         gGetContextualMenuProc   
  312. dim as proc                         gSelectContextualMenuProc
  313.  
  314. dim as proc                         gDialogEventHandlerProc  
  315. dim as proc                         gWindowEventHandlerProc  
  316.  
  317. end globals
  318.  
  319. '~------
  320. '~Prototype Functions
  321. /*
  322.      I have changed the original coding using here protoype functions
  323.      that the callback procedures will use.
  324.      The local functions that will be actually called by the procedures are
  325.      set in SetupMyVectors fn.
  326. */
  327. def fn Proto_PlacardDraw( c as ControlRef, dummy as SInt16 ) using gPlacardDrawProc
  328.  
  329. def fn Proto_AcceptDrag( browser as ControlRef, theDrag as DragReference, itemID as DataBrowserItemID ) using gAcceptDragProc
  330. def fn Proto_ReceiveDrag( browser as ControlRef, theDrag as DragReference, itemID as DataBrowserItemID ) using gReceiveDragProc
  331. def fn Proto_AddDragItem( browser as ControlRef, theDrag as DragReference, inItemID as DataBrowserItemID, itemRef as .ItemReference ) using gAddDragItemProc
  332. def fn Proto_GetSetItemData( browser as ControlRef, itemID as DataBrowserItemID, prop as DataBrowserPropertyID, itemData as DataBrowserItemDataRef, changeValue as Boolean ) using gGetSetItemDataProc
  333. def fn Proto_ItemComparison( browser as ControlRef, itemOneID as DataBrowserItemID, itemTwoID as DataBrowserItemID, sortProperty as DataBrowserPropertyID ) using gItemComparisonProc
  334. def fn Proto_ItemNotification( browser as ControlRef, itemID as DataBrowserItemID, message as DataBrowserItemNotification ) using gItemNotificationProc
  335. def fn Proto_ItemHelpContent(browser as ControlRef,item as DataBrowserItemID,prop as DataBrowserPropertyID,inRequest as HMContentRequest,outContentProvided as .HMContentProvidedType, ioHelpContent as .HMHelpContentRec ) using gItemHelpContentProc
  336. def fn Proto_ContextualMenu( browser as ControlRef, contextualMenu as .MenuRef, helpType as .UInt32, helpItemString as .CFStringRef, selection as .AEDesc ) using gGetContextualMenuProc
  337. def fn Proto_SelectContextualMenu( browser as ControlRef, contextualMenu as MenuRef, selectionType as UInt32, menuID as SInt16, menuItem as MenuItemIndex  ) using gSelectContextualMenuProc
  338.  
  339. def fn Proto_DialogEventHandler( EventHandlerCallRef as ptr, inEvent as EventRef, void as ptr ) using gDialogEventHandlerProc
  340. def fn Proto_WindowEventHandler( EventHandlerCallRef as ptr, inEvent as EventRef, void as ptr ) using gWindowEventHandlerProc
  341.  
  342. '~';
  343. '~-
  344. '~Utility Functions
  345.  
  346. def fn InstallWindowEventHandler( t, h, n, @l, @u, @r ) = fn InstallEventHandler( fn GetWindowEventTarget( t ), h, n, #l, #u, #r )
  347. def fn SendEventToWindow( e, t ) = fn SendEventToEventTarget( e, fn GetWindowEventTarget( t ) )
  348.  
  349. /*
  350.      This is a dummy function, never called by the program, just
  351.      here to store string lists (easier to edit in the source code)
  352. */
  353. local Fn CreateStrLists
  354.  
  355. dim as str255 s
  356.  
  357. begin enum 128
  358. _flavorListResID
  359. _colorListResID
  360. _commentListResID
  361. end enum
  362.  
  363. stringlist on
  364. stringlist  = _flavorListResID,"Flavors"
  365. s = "Lime"
  366. s = "Tangerine"
  367. s = "Strawberry"
  368. s = "Grape"
  369. s = "Blueberry"
  370. stringlist end
  371.  
  372. stringlist = _colorListResID  ,"Colors"
  373. s = "Green"
  374. s = "Orange"
  375. s = "Red"
  376. s = "Purple"
  377. s = "Blue"
  378. stringlist end
  379.  
  380. stringlist = _commentListResID,"Help tags"
  381. s = "Lime is luscious."
  382. s = "Tangerine is Tangy."
  383. s = "Strawberry is Super!"
  384. s = "Grape is grand."
  385. s = "Blueberry is nice."
  386. stringlist end
  387.  
  388. end fn
  389.  
  390. '~'1
  391. /*
  392.      Display an alert just to show something on screen
  393. */
  394. clear local fn ShowMe( message as Str255 )
  395.  
  396. dim as AlertStdAlertParamRec  alertParams
  397. dim as SInt16               @ itemHit
  398.  
  399. alertParams.movable       = _true
  400. alertParams.helpButton    = _false
  401. alertParams.filterProc    = _nil'TEventDispatcher::ModalFilter()
  402. alertParams.defaultText   = _kAlertDefaultOKText
  403. alertParams.cancelText    = _nil
  404. alertParams.otherText     = _nil
  405. alertParams.defaultButton = _kAlertStdAlertOKButton
  406. alertParams.cancelButton  = 0
  407. alertParams.position      = _kWindowDefaultPosition
  408.  
  409. end fn = fn StandardAlert( _kAlertPlainAlert, message, _nil, alertParams, itemHit )
  410.  
  411. '~';
  412. '~--
  413. '~Application Functions
  414. /*
  415.      Those are functions avoiding to repeat test code elsewhere.
  416.      They check if a given item must be shown as an alias in the list
  417.      and if a given item is a container (i.e. has subitems)
  418. */
  419. def fn IsAlias( itemID ) = ( itemID == 44 || itemID == 486 || itemID == 509 )
  420. def fn IsContainer( itemID ) = ( not( ( (itemID mod 5) == 2 or itemID > 10000) ) and not( fn IsAlias( itemID ) ) )
  421.  
  422. '~';
  423. /*
  424.      This function is used to create a string, it is used more precisely
  425.      for the cells under the column titled ItemID that the DataBrowser
  426.      must display.
  427. */
  428. clear local fn GenerateString( itemID as DataBrowserItemID, inProp as DataBrowserPropertyID, @s as .Str255 )
  429.  
  430. dim as Str255                  tempStr
  431. dim as DataBrowserPropertyID @ prop 
  432. dim as Boolean                 itemXProperty
  433.  
  434. prop = inProp
  435. s.nil` = 0
  436. itemXProperty = ( prop == _itemIDColumnID or prop == _kDataBrowserItemSelfIdentityProperty )
  437.  
  438. if itemXProperty then s.nil$ = "Item "
  439. s.nil$ = s.nil$ + str$( itemID )
  440.  
  441. long if not( itemXProperty )
  442. tempStr[0] = sizeof(prop)
  443. BlockMoveData( @prop, @tempStr[1], sizeof(prop) )
  444. s.nil$ = s.nil$ + ", " + tempStr
  445. end if
  446.  
  447. end fn
  448.  
  449. '~'1
  450. /*
  451.      This function retrieves the browser reference from the window.
  452.      The browser reference has been saved has a window property.
  453. */
  454. clear local fn GetDataBrowserFromWindow( w as WindowRef )
  455.  
  456. dim as OSStatus     err
  457. dim as ControlRef @ browser
  458.  
  459. long if w
  460. err = fn GetWindowProperty( w, _myCreator, _myDataBrowser, sizeof(browser), #_nil, browser )
  461. end if
  462.  
  463. end fn = browser
  464.  
  465. '~Customizer & Settings Dialogs
  466. '~';
  467. /*
  468.      This function will tell if a given feature is enabled for the
  469.      selection mode used with the DataBrowser. 
  470.      The selection flags can be a combination of the following:
  471.  
  472.           constant name                                   description
  473.  
  474.      _kDataBrowserDragSelect             This turns on or off the availability of the
  475.                                          selection marque. The marque will show up if
  476.                                          the click was not on content, or the Option key
  477.                                          is not down and _kDataBrowserDragSelect is on
  478.                                          _kDataBrowserSelectOnlyOne is off and 
  479.                                          _kDataBrowserNoDisjointSelection is off.
  480.  
  481.      _kDataBrowserSelectOnlyOne          allow only one item to be selected at once.
  482.  
  483.      _kDataBrowserResetSelection         reset list before processing next selection
  484.                                          operation.
  485.  
  486.      _kDataBrowserCmdTogglesSelection    allow use of command to toggle items in and
  487.                                          out of the selection.
  488.  
  489.      _kDataBrowserNoDisjointSelection    prevent discontinuous selections. 
  490.  
  491.      _kDataBrowserAlwaysExtendSelection  enable multiple item selection without holding
  492.                                          down any modifier keys.
  493.  
  494. */
  495. clear local fn SelectionFlagOn( browser as ControlRef, flag as DataBrowserSelectionFlags )
  496.  
  497. dim as DataBrowserSelectionFlags @ flags
  498. dim as OSStatus                    err
  499.  
  500. long if browser
  501. err = fn GetDataBrowserSelectionFlags( browser, flags )
  502. end if
  503.  
  504. end fn = ( flags and flag ) <> 0// I hope it is OK
  505.  
  506. '~';
  507. /*
  508.      This function will setup the buttons in the customizer windows.
  509.      There are two dialogs to play with the DataBrowser settings
  510.      in this program.
  511. */
  512. clear local fn SetupControls( dlog as DialogRef, customizerID as UInt16)
  513.  
  514. dim as OSStatus                          err
  515. dim as DialogItemIndex                   dItem
  516. dim as ControlRef                        browser, @ c
  517. dim as UInt32                          @ numColumns
  518. dim as UInt16                          @ headerBtnHeight
  519. dim as DataBrowserPropertyFlags        @ flags
  520. dim as DataBrowserTableViewHiliteStyle @ hiliteStyle
  521. dim as DataBrowserPropertyID           @ disclosureColumn
  522. dim as Boolean                         @ cVal, vBar, hBar, expandableRows
  523.  
  524. browser  = fn GetDataBrowserFromWindow( fn GetDialogWindow(dlog) )
  525.  
  526. do
  527. dItem++
  528. if fn GetDialogItemAsControl( dlog, dItem, c ) != _noErr then exit do
  529.  
  530. long if c
  531. // Set a custom ID for each control's reference (here its index in the control list)
  532. SetControlReference( c, dItem )
  533.  
  534. select customizerID
  535.  
  536. case _settingsDLOGResID:
  537. '~'2
  538.  
  539. select dItem
  540.  
  541. case _activeItemsBtn  : err = fn GetDataBrowserActiveItems( browser, cVal )
  542. case _frameAndFocusBtn: err = fn GetControlData( browser, _kControlNoPart, _kControlDataBrowserIncludesFrameAndFocusTag, sizeof(cVal), cVal, #_nil)
  543. case _verticalScrollBtn, _horizontalScrollBtn:
  544.  
  545. err = fn GetDataBrowserHasScrollBars( browser, hBar, vBar )
  546. select dItem
  547. case _verticalScrollBtn  : cVal = vBar
  548. case _horizontalScrollBtn: cVal = hBar
  549. end select
  550.  
  551. case _dragSelectBtn    : cVal = fn SelectionFlagOn( browser, _kDataBrowserDragSelect )
  552. case _selectOnlyOneBtn : cVal = fn SelectionFlagOn( browser, _kDataBrowserSelectOnlyOne )
  553. case _resetSelectionBtn: cVal = fn SelectionFlagOn( browser, _kDataBrowserResetSelection )
  554. case _commandTogglesBtn: cVal = fn SelectionFlagOn( browser, _kDataBrowserCmdTogglesSelection )
  555. case _noDisjointBtn    : cVal = fn SelectionFlagOn( browser, _kDataBrowserNoDisjointSelection )
  556. case _alwaysExtendBtn  : cVal = fn SelectionFlagOn( browser, _kDataBrowserAlwaysExtendSelection )
  557.  
  558. end select
  559.  
  560. case _customizeDLOGResID:
  561. '~'2
  562.  
  563. select dItem
  564.  
  565. case _varHeightRowsBtn:
  566.  
  567. err = fn GetDataBrowserTableViewGeometry( browser, #_nil, cVal )
  568. /*
  569.      fn GetDataBrowserTableViewGeometry ( browser, variableWidthColumns, variableHeightRows )
  570.  
  571.      variableWidthColumns     true if the DataBrowser has variable
  572.                               width columns
  573.  
  574.      variableHeightRows       true if the DataBrowser has variable
  575.                               height rows (currently ignored)
  576. */
  577. long if cVal = _false
  578. err = fn GetDialogItemAsControl( dlog, _expandableRowsBtn, c )
  579. err = fn DeactivateControl( c )
  580. end if
  581.  
  582. case _disclosureBtn, _expandableRowsBtn:
  583.  
  584. err = fn GetDataBrowserListViewDisclosureColumn( browser, disclosureColumn, expandableRows )
  585. /*
  586.      disclosureColumn   the column Property ID of the column where
  587.                         the disclosure triangles are being displayed.
  588.  
  589.      expandableRows     if the row itself expands rather than opening up
  590.                         several sub-rows, then this parameter will be
  591.                         set to true.
  592. */
  593.  
  594. long if dItem != _disclosureBtn
  595. cVal = expandableRows
  596. xelse
  597. long if disclosureColumn
  598. // setup the value for the popup menu control
  599. err = fn GetDataBrowserTableViewColumnCount( browser, numColumns )
  600. while numColumns
  601. numColumns--
  602. if disclosureColumn == gCols(numColumns) then cVal = numColumns + 3 : exit while
  603. wend
  604. end if
  605. end if
  606.  
  607. case _useRelativesDatesBtn:
  608.  
  609. err  = fn GetDataBrowserPropertyFlags( browser, _dateTimeColumnID, flags )
  610. cVal = flags and _kDataBrowserDateTimeRelative
  611.  
  612. case _fillHiliteStyleBtn:
  613.  
  614. err  = fn GetDataBrowserTableViewHiliteStyle( browser, hiliteStyle )
  615. cVal = hiliteStyle
  616.  
  617. case _showHeaderButtonsBtn:
  618. err  = fn GetDataBrowserListViewHeaderBtnHeight( browser, headerBtnHeight )
  619. cVal = abs( headerBtnHeight != 0 )// ABS needed because _zTrue (-1) won't work
  620.  
  621. case _plainBackgroundBtn:
  622. err = fn GetDataBrowserListViewUsePlainBackground( browser, cVal )
  623.  
  624. end select
  625.  
  626. end select
  627.  
  628. SetControlValue( c, cVal )
  629.  
  630. end if
  631.  
  632. until _nil// loop exit on error
  633.  
  634. end fn
  635.  
  636. '~';
  637. /*
  638.      This function will return the dialogRef of one of the two
  639.      customizer windows. The dialogRef has previously been stored
  640.      as a browser property.
  641. */
  642. clear local fn GetCustomizer( browser as ControlRef, customizerID as UInt16 )
  643.  
  644. dim as OSStatus    err
  645. dim as DialogRef @ customizer
  646.  
  647. long if browser
  648. err = fn GetControlProperty( browser, _myCreator, customizerID, sizeof(customizer), #_nil, customizer )
  649. end if
  650.  
  651. end fn = customizer
  652.  
  653. '~';
  654. /*
  655.      Given a customizer window reference the function will
  656.      return the customizer ID.
  657. */
  658. clear local fn GetCustomerID( customizer as WindowRef )
  659.  
  660. dim as OSStatus err
  661. dim as UInt16 @ customizerID
  662.  
  663. long if customizer
  664. err = fn GetWindowProperty( customizer, _myCreator, _myCustomizerID, sizeof(customizerID), #_nil, customizerID )
  665. end if
  666.  
  667. end fn = customizerID
  668.  
  669. '~';
  670. /*
  671.      This function will display or create our two dialogs for
  672.      customization.
  673. */
  674. clear local fn SetupCustomizer( inBrowser as ControlRef, inCustomizerID as UInt16 )
  675.  
  676. dim as OSStatus       err
  677. dim as WindowRef      w
  678. dim as DialogRef    @ customizer
  679. dim as UInt16       @ customizerID
  680. dim as proc         @ eventHandler
  681. dim as ControlRef   @ browser
  682. dim as EventTypeSpec  events(3)
  683.  
  684. browser      = inBrowser// RAM variable needed
  685. customizerID = inCustomizerID// idem
  686.  
  687. /*
  688.      Get the customizer (DialogRef) with the customizerID (custom identifier)
  689.      previously stored as a control property for the DataBrowser
  690. */
  691. customizer   = fn GetCustomizer( browser, customizerID )
  692.  
  693. long if customizer == _nil// this customizer is not currently open
  694.  
  695. customizer = fn GetNewDialog( customizerID, _nil, -1 )
  696.  
  697. long if customizer
  698. w          = fn GetDialogWindow( customizer )
  699. err        = fn InstallStandardEventHandler( fn GetWindowEventTarget( w ) )
  700.  
  701. // Store our custom dialog identifier as a browser property
  702. err = fn SetControlProperty( browser, _myCreator, customizerID, sizeof(customizer), customizer )
  703.  
  704. // Store browser as a property of that dialog window
  705. err = fn SetWindowProperty( w, _myCreator, _myDataBrowser, sizeof(ControlRef), browser )
  706.  
  707. // Setup initial control values
  708. fn SetupControls( customizer, customizerID )
  709. err = fn SetWindowClass( w, _kFloatingWindowClass )
  710.  
  711. // Store event handler as a window property
  712. events.eventClass(0) = _kEventClassWindow
  713. events.eventKind (0) = _kEventWindowClose
  714.  
  715. events.eventClass(1) = _kEventClassControl
  716. events.eventKind (1) = _kEventControlHit
  717.  
  718. events.eventClass(2) = _kEventClassCommand
  719. events.eventKind (2) = _kEventCommandProcess
  720.  
  721. events.eventClass(3) = _kEventClassCommand
  722. events.eventKind (3) = _kEventCommandUpdateStatus
  723.  
  724. eventHandler = fn NewEventHandlerUPP( [proc "DialogEventHandlerProc" + _FBprocToProcPtrOffset] )
  725.  
  726. long if fn InstallWindowEventHandler( w, eventHandler, sizeof(events(0))*4, events(0), #_nil, #_nil )
  727. DisposeDialog( customizer ) : exit fn
  728. end if
  729.  
  730. err = fn SetWindowProperty( w, _myCreator, _myEventHandler, sizeof(eventHandler), eventHandler )
  731. // Store customizerID as a window property
  732. err = fn SetWindowProperty( w, _myCreator, _myCustomizerID, sizeof(customizerID), customizerID )
  733. end if
  734.  
  735. xelse
  736.  
  737. w = fn GetDialogWindow( customizer )
  738. ShowWindow( w )
  739. SelectWindow( w )
  740.  
  741. end if
  742.  
  743. end fn
  744.  
  745. '~';
  746. /*
  747.      Some checkboxes are linked together in the settings dialog, this function
  748.      will activate or deasctivate controls depending on the current value
  749.      set for another one.
  750. */
  751. clear local fn ActivateControlInDialog( dlog as DialogRef, dItem as UInt8, numItems as UInt8, items(_maxint) as UInt8 )
  752.  
  753. dim as ControlRef @ c
  754. dim as OSStatus     err
  755. dim as long         i
  756. dim as boolean      active
  757.  
  758. for i = 0 to numItems - 1
  759. long if fn GetDialogItemAsControl( dlog, items(i), c ) = _noErr
  760. active = fn GetControlValue( c )
  761. end if
  762. if active then exit for
  763. next
  764.  
  765. long if fn GetDialogItemAsControl(  dlog, dItem, c ) = _noErr
  766. long if active
  767. err = fn DeactivateControl( c )
  768. xelse
  769. err = fn ActivateControl( c )
  770. end if
  771. end if
  772.  
  773. end fn
  774.  
  775. '~';
  776. /*
  777.      This function checks if a given flag is enabled for the DataBrowser
  778.      then update the value of a given button accordingly.
  779. */
  780. clear local fn ToggleSelectionFlag( browser as ControlRef, flag as DataBrowserSelectionFlags, c as ControlRef )
  781.  
  782. dim as DataBrowserSelectionFlags @ flags
  783. dim as OSStatus                    err
  784.  
  785. err = fn GetDataBrowserSelectionFlags( browser, flags )
  786. err = fn SetDataBrowserSelectionFlags( browser, flags xor flag )
  787.  
  788. //Make sure flag and representative control are synch'd
  789. long if flags and flag
  790. SetControlValue( c, _kThemeButtonOff )
  791. xelse
  792. SetControlValue( c, _kThemeButtonOn )
  793. end if
  794.  
  795. end fn// = not( flags and flag )
  796.  
  797. '~';
  798. /*
  799.      This is where the action are triggered for our two dialogs
  800.      for costumization. It will update the features of the
  801.      DataBrowser according to the selection of the end user.
  802. */
  803. clear local fn HandleCustomizerControl( inCntl as ControlRef )
  804.  
  805. dim as WindowRef                  w
  806. dim as DialogItemIndex            dItem
  807. dim as ControlRef                 browser, @ cmdTogglesCntrl, c
  808. dim as DialogRef                  dlog
  809. dim as OSStatus                   err
  810. dim as Rect                       sInset
  811. dim as UInt16                  @  headerBtnHeight
  812. dim as ThemeButtonValue           value
  813. dim as UInt8                      i
  814. dim as UInt8                      dragSelectOverrides(1)
  815. dim as UInt8                      alwaysExtendOverrides(1)
  816. dim as UInt8                      overrides(3)
  817. dim as DataBrowserPropertyFlags @ flags
  818. dim as DataBrowserPropertyID    @ disclosureColumn
  819. dim as Boolean                  @ cVal, expandableRows, vBar, hBar, bool
  820.  
  821. c       = inCntl// local copy of the controlRef for RAM variable
  822. w       = fn GetControlOwner( c )// windowRef of the window owning the control
  823. cVal    = fn GetControlValue( c )// current control value
  824. dItem   = fn GetControlReference( c )// get our custom identifier for that control
  825. browser = fn GetDataBrowserFromWindow( w )// get the DataBrowser control from the windowRef
  826.  
  827. select fn GetCustomerID( w )// which custom identifer for that dialog window
  828.  
  829. case _customizeDLOGResID:
  830. '~'2
  831.  
  832. select dItem
  833.  
  834. case _disclosureBtn, _expandableRowsBtn:// 2 controls treated here
  835.  
  836. err = fn GetDataBrowserListViewDisclosureColumn( browser, disclosureColumn, expandableRows )
  837. long if dItem != _disclosureBtn
  838. expandableRows = cVal
  839. xelse
  840. long if cVal < 3// cVal is the popup menu item chosen
  841. disclosureColumn = _kDataBrowserItemNoProperty
  842. xelse
  843. disclosureColumn = gCols(cVal-3)
  844. end if
  845. end if
  846. err = fn SetDataBrowserListViewDisclosureColumn( browser, disclosureColumn, expandableRows )
  847.  
  848. case _showHeaderButtonsBtn:
  849.  
  850. err  = fn GetDataBrowserListViewHeaderBtnHeight( browser, headerBtnHeight )
  851. select
  852. case cVal != 0 and headerBtnHeight == 0 : headerBtnHeight = _btnHeight // checked "Show Headers" checkbox and header currently invisible
  853. case cVal == 0 and headerBtnHeight != 0 : headerBtnHeight = 0// unchecked "Show Headers" checkbox and header currently visible
  854. end select
  855. err = fn SetDataBrowserListViewHeaderBtnHeight( browser, headerBtnHeight )
  856.  
  857. case _fillHiliteStyleBtn:
  858.  
  859. err = fn SetDataBrowserTableViewHiliteStyle( browser, cVal )// pass just the "Fill Hilite" checkbox value to the DataBrowser
  860.  
  861. case _useRelativesDatesBtn:
  862.  
  863. err = fn GetDataBrowserPropertyFlags( browser, _dateTimeColumnID, flags )// just toggle the current flag
  864. err = fn SetDataBrowserPropertyFlags( browser, _dateTimeColumnID, flags xor _kDataBrowserDateTimeRelative )
  865.  
  866. case _varHeightRowsBtn:
  867. /*
  868.  GetDataBrowserTableViewGeometry (browser, variableWidthColumns, variableHeightRows)
  869. */
  870.  
  871. err = fn GetDataBrowserTableViewGeometry( browser, bool, cVal )
  872. err = fn SetDataBrowserTableViewGeometry( browser, bool, -(cVal == 0) )//not(cVal)
  873.  
  874. SetControlValue( c, -(cVal == 0) )//not(cVal)
  875.  
  876. err = fn GetDialogItemAsControl( fn GetDialogFromWindow( fn GetControlOwner( c ) ), _expandableRowsBtn, c )
  877.  
  878. long if cVal
  879. err = fn ActivateControl( c )
  880. xelse
  881. err = fn DeactivateControl( c )
  882. end if
  883.  
  884. case _plainBackgroundBtn:
  885. err = fn SetDataBrowserListViewUsePlainBackground( browser, cVal )
  886.  
  887. end select
  888.  
  889.  
  890. case _settingsDLOGResID:
  891. '~'2
  892.  
  893. dlog = fn GetDialogFromWindow( w )
  894.  
  895. select dItem
  896.  
  897. case _frameAndFocusBtn:
  898.  
  899. err = fn SetControlData( browser, _kControlNoPart, _kControlDataBrowserIncludesFrameAndFocusTag, sizeof(cVal), cVal )
  900.  
  901. case _activeItemsBtn:
  902.  
  903. err = fn SetDataBrowserActiveItems( browser, cVal )
  904.  
  905. case _verticalScrollBtn, _horizontalScrollBtn:
  906.  
  907. err = fn GetDataBrowserHasScrollBars( browser, hBar, vBar )
  908.  
  909. select dItem
  910. case _verticalScrollBtn  : if vBar then vBar = _false else vBar = _true
  911. case _horizontalScrollBtn: if hBar then hBar = _false else hBar = _true
  912. end select
  913.  
  914. err = fn SetDataBrowserHasScrollBars( browser, hBar, vBar )
  915.  
  916. long if hBar or vBar
  917. err = fn GetDataBrowserScrollBarInset( browser, sInset )
  918. if hBar then sInset.right  = _scrollBarWidth - 1
  919. if vBar then sInset.bottom = _scrollBarWidth - 1
  920. err = fn SetDataBrowserScrollBarInset( browser, sInset )
  921. end if
  922.  
  923. case _dragSelectBtn      : fn ToggleSelectionFlag( browser, _kDataBrowserDragSelect, c )
  924. case _selectOnlyOneBtn   : fn ToggleSelectionFlag( browser, _kDataBrowserSelectOnlyOne, c )
  925. case _resetSelectionBtn  : fn ToggleSelectionFlag( browser, _kDataBrowserResetSelection, c )
  926. case _commandTogglesBtn  : fn ToggleSelectionFlag( browser, _kDataBrowserCmdTogglesSelection, c )
  927. case _noDisjointBtn      : fn ToggleSelectionFlag( browser, _kDataBrowserNoDisjointSelection, c )
  928. case _alwaysExtendBtn    : fn ToggleSelectionFlag( browser, _kDataBrowserAlwaysExtendSelection, c )
  929.  
  930. /*
  931. case _noEmptySelectionBtn: fn ToggleSelectionFlag( browser, _kDataBrowserNeverEmptySelectionSet, c )
  932. */
  933. end select
  934.  
  935. /*
  936.      A few checkboxes are linked together, so the following
  937.      piece of code overrides the end user selection.
  938. */
  939. select dItem
  940.  
  941. case _noDisjointBtn, _selectOnlyOneBtn, _resetSelectionBtn, _commandTogglesBtn, _noEmptySelectionBtn:
  942.  
  943. dragSelectOverrides(0) = _noDisjointBtn
  944. dragSelectOverrides(1) = _selectOnlyOneBtn
  945. fn ActivateControlInDialog( dlog, _dragSelectBtn, 2, @dragSelectOverrides(0) )
  946.  
  947. alwaysExtendOverrides(0) = _selectOnlyOneBtn
  948. alwaysExtendOverrides(1) = _resetSelectionBtn
  949. fn ActivateControlInDialog( dlog, _alwaysExtendBtn, 2, @alwaysExtendOverrides(0))
  950.  
  951. long if fn GetDialogItemAsControl( dlog, _commandTogglesBtn, cmdTogglesCntrl) = _noErr
  952. long if fn GetControlValue( cmdTogglesCntrl )
  953. value = _kThemeButtonOn
  954. overrides(0) = _noDisjointBtn
  955. overrides(1) = _selectOnlyOneBtn
  956. overrides(2) = _resetSelectionBtn
  957. overrides(3) = _noEmptySelectionBtn
  958. for i = 0 to 3
  959. long if fn GetDialogItemAsControl( dlog, overrides(i), c ) = _noErr
  960. if fn GetControlValue( c ) then value = _kThemeButtonMixed : exit for
  961. end if
  962. next
  963. SetControlValue( cmdTogglesCntrl, value )
  964. end if
  965. end if
  966.  
  967. end select
  968.  
  969. end select
  970.  
  971. end fn
  972.  
  973. '~-----
  974. '~DataBrowser Drag & Drop
  975. /*
  976.      This function tells the DataBrowser if a dragged item is
  977.      acceptable or not. It is invoked via a specific callback procedure.
  978. */
  979. clear local fn MyAcceptDrag( browser as ControlRef, theDrag as DragReference, itemID as DataBrowserItemID )
  980.  
  981. dim as ThemeCursor         curs
  982. dim as OSStatus            err
  983. dim as SInt16            @ modifiers
  984. dim as DataBrowserItemID @ target
  985. dim as boolean             accept
  986.  
  987. accept = fn IsContainer( itemID )
  988.  
  989. long if accept
  990. curs  = _kThemeArrowCursor
  991. err   = fn GetDragModifiers( theDrag, modifiers, #_nil, #_nil )
  992.  
  993. select
  994.  
  995. case ( modifiers and _cmdKey%_optionKey% ) =  _cmdKey%_optionKey%: curs = _kThemeAliasArrowCursor
  996. case ( modifiers and _optionKey% )         = _optionKey%         : curs = _kThemeCopyArrowCursor
  997.  
  998. case ( modifiers and _cmdKey% ) = _cmdKey% :
  999. target = _kDataBrowserNoItem
  1000. err    = fn GetDataBrowserTarget( browser, target )
  1001. if ( itemID != target ) then accept = _false
  1002.  
  1003. end select
  1004.  
  1005. err = fn SetThemeCursor( curs )
  1006. end if
  1007.  
  1008. end fn = accept
  1009.  
  1010. '~';
  1011. /*
  1012.      This function is called via a callback procedure, when an
  1013.      item has been dropped somewhere in the list. The itemID
  1014.      holds the target container, the item/s beeing dropped is/are
  1015.      retrieved from the drag reference.
  1016.      
  1017.      The state of the target container can be examined with:
  1018.  
  1019.      GetDataBrowserItemState( browser, itemID, itemState )
  1020.     
  1021.       The possible states are:
  1022.  
  1023.           constant name                     description
  1024.      _kDataBrowserItemNoState       has no state associated with it at this time. 
  1025.      _kDataBrowserItemIsSelected    is a member of the current selection. 
  1026.      _kDataBrowserContainerIsOpen   disclosure open. 
  1027.      _kDataBrowserItemIsDragTarget  Only true during a drag operation. 
  1028. */
  1029. clear local fn MyReceiveDrag( browser as ControlRef, theDrag as DragReference, itemID as DataBrowserItemID )
  1030.  
  1031. dim as UInt32                 i
  1032. dim as OSStatus               err
  1033. dim as Size                 @ dataSize
  1034. dim as DataBrowserItemID    @ draggedItem
  1035. dim as ItemReference        @ itemRef
  1036. dim as UInt16               @ numItems
  1037. dim as DataBrowserItemState @ itemState
  1038.  
  1039. itemState = 0
  1040.  
  1041. long if itemID == _kDataBrowserNoItem// dropped over nothing
  1042. itemState = _kDataBrowserContainerIsOpen// in that test we'll accept only on open containers
  1043. xelse
  1044. err = fn GetDataBrowserItemState( browser, itemID, itemState )// get the state of the target container
  1045. end if
  1046.  
  1047. long if itemState and _kDataBrowserContainerIsOpen
  1048.  
  1049. err = fn CountDragItems( theDrag, numItems )
  1050. long if numItems
  1051. for i = 1 to numItems
  1052. dataSize = sizeof(draggedItem)
  1053. err   = fn GetDragItemReferenceNumber( theDrag, i, itemRef )
  1054. err   = fn GetFlavorData( theDrag, itemRef, _typeUInt32, draggedItem, dataSize, 0 )
  1055. err   = fn RemoveDataBrowserItems( browser, _kDataBrowserNoItem, 1, draggedItem, _kDataBrowserItemNoProperty )
  1056. err   = fn AddDataBrowserItems( browser, itemID, 1, draggedItem, _kDataBrowserItemNoProperty )
  1057. next
  1058. end if
  1059.  
  1060. // Rem'd out in the original Apple demo
  1061. dim as Str255  s
  1062. s = "Drag received in "
  1063. select itemID
  1064. case _nil : s += "list"
  1065. case else : s += "Item " + str$( itemID )
  1066. end select
  1067. fn ShowMe( s )
  1068.  
  1069. end if
  1070.  
  1071. end fn = _true
  1072.  
  1073. '~'1
  1074. /*
  1075.      This function is invoked by a callback procedure, to let you
  1076.      add an item for the drag operation.
  1077. */
  1078. clear local fn MyAddDragItem( browser as ControlRef, theDrag as DragReference, inItemID as DataBrowserItemID, itemRef as .ItemReference )
  1079.  
  1080. dim as Str255              s
  1081. dim as OSStatus            err
  1082. dim as DataBrowserItemID @ itemID
  1083.  
  1084. itemID  = inItemID// must be in RAM
  1085.  
  1086. fn GenerateString( itemID, _"col4", s )
  1087. s += chr$(13)
  1088.  
  1089. err = fn GetDragItemReferenceNumber( theDrag, 1, #itemRef )
  1090. err = fn AddDragItemFlavor( theDrag, itemRef.nil&, _"TEXT", @s[1], s[0], 0 )
  1091. err = fn AddDragItemFlavor( theDrag, itemRef.nil&, _typeUInt32, @itemID, sizeof(itemID), 0 )
  1092.  
  1093. end fn = _true // for automatic transluscent dragging
  1094.  
  1095. '~DataBrowser Setting & Getting Data
  1096. '~'1
  1097. /*
  1098.      This function is called via a callback procedure. This is
  1099.      the only required routine to work with a DataBrowser control.
  1100.      The DataBrowser asks you to setup some values for the cells
  1101.      that it must display. Those values are set with specific functions
  1102.      depending on the type of the cell to be updated.
  1103.      With the same callback routine the DataBrowser may inform you
  1104.      that a cell has been changed by the end user, so it is time
  1105.      to get the value sent by the DataBrowser to update your
  1106.      internal information.
  1107.      Here, we don't have a real set of items to update, since
  1108.      they are faked with calculation.
  1109. */
  1110. clear local fn MyGetSetItemData( browser as ControlRef, itemID as DataBrowserItemID, prop as DataBrowserPropertyID, itemData as DataBrowserItemDataRef, changeValue as Boolean )
  1111.  
  1112. dim as OSStatus    err
  1113. dim as CFStringRef txt
  1114. dim as SInt16      mod5
  1115. dim as Str255      s
  1116. dim as LongDateCvt dt
  1117.  
  1118. err = _noErr
  1119.  
  1120. long if changeValue = _false
  1121.  
  1122. select prop
  1123.  
  1124.  
  1125. case _checkboxColumnID:
  1126.  
  1127. long if ( itemID mod 5 ) == 2
  1128. err = fn SetDataBrowserItemDataButtonValue( itemData, _kThemeButtonMixed )
  1129. err = fn SetDataBrowserItemDataDrawState( itemData, _kThemeStateInactive )
  1130. end if
  1131.  
  1132.  
  1133. case _flavorColumnID, _iconOnlyColumnID
  1134.  
  1135. long if prop == _flavorColumnID// Fall through to _iconOnlyColumnID
  1136. s   = str#( _flavorListResID, ( itemID mod 5 ) + 1 )
  1137. txt = fn CFStringCreateWithPascalString( fn CFAllocatorGetDefault, s, _kCFStringEncodingMacRoman )
  1138. err = fn SetDataBrowserItemDataText( itemData, txt ) : CFRelease( txt )
  1139. end if
  1140.  
  1141. long if fn IsContainer( itemID )
  1142. err = fn SetDataBrowserItemDataIcon( itemData, gIcon(_folderIndex) )
  1143. xelse
  1144. long if fn IsAlias( itemID )
  1145. err = fn SetDataBrowserItemDataIcon( itemData, gIcon(_folderAliasIndex) )
  1146. xelse
  1147. err = fn SetDataBrowserItemDataIcon( itemData, gIcon(_documentIndex) )
  1148. end if
  1149. end if
  1150.  
  1151.  
  1152. case _colorColumnID:
  1153.  
  1154. s   = str#( _colorListResID, ( itemID mod 5 ) + 1 )
  1155. txt = fn CFStringCreateWithPascalString( fn CFAllocatorGetDefault, s, _kCFStringEncodingMacRoman )
  1156. err = fn SetDataBrowserItemDataText( itemData, txt ) : CFRelease( txt )
  1157.  
  1158.  
  1159. case _indexColumnID:
  1160.  
  1161. mod5 = itemID mod 5
  1162. if mod5 == 0 then mod5 = 5
  1163. NumToString( mod5, s )
  1164. txt = fn CFStringCreateWithPascalString( fn CFAllocatorGetDefault, s, _kCFStringEncodingMacRoman )
  1165. err = fn SetDataBrowserItemDataText( itemData, txt ) : CFRelease( txt )
  1166.  
  1167.  
  1168. case _dateTimeColumnID:
  1169.  
  1170. dt.hl.lHigh = 0
  1171. GetDateTime( dt.hl.lLow )
  1172. dt.hl.lLow -= ( ( (itemID - 1) mod 10 ) * 28800 )
  1173. err = fn SetDataBrowserItemDataLongDateTime( itemData, dt.c )
  1174.  
  1175.  
  1176. case _sliderColumnID, _progressColumnID:
  1177.  
  1178. err = fn SetDataBrowserItemDataValue( itemData, ( itemID mod 5 ) * 20 )
  1179.  
  1180.  
  1181. case _popupMenuColumnID:
  1182.  
  1183. long if ( itemID mod 5 + 1 ) != 1
  1184. err = fn SetDataBrowserItemDataMenuRef( itemData, gContextualMenu )
  1185. end if
  1186. err = fn SetDataBrowserItemDataValue( itemData, ( itemID mod 5 ) + 1 )
  1187.  
  1188.  
  1189. case _kDataBrowserItemSelfIdentityProperty, _itemIDColumnID
  1190.  
  1191. long if prop == _kDataBrowserItemSelfIdentityProperty// can display icon & text, so fall through to text generator
  1192. select
  1193. case fn IsContainer( itemID ) : err = fn SetDataBrowserItemDataIcon( itemData, gIcon(_folderIndex)      )
  1194. case fn IsAlias( itemID )     : err = fn SetDataBrowserItemDataIcon( itemData, gIcon(_folderAliasIndex) )
  1195. case else                     : err = fn SetDataBrowserItemDataIcon( itemData, gIcon(_documentIndex)    )
  1196. end select
  1197. end if
  1198.  
  1199. fn GenerateString( itemID, prop, s ) // case _itemIDColumnID
  1200. txt = fn CFStringCreateWithPascalString( fn CFAllocatorGetDefault, s, _kCFStringEncodingMacRoman )
  1201. err = fn SetDataBrowserItemDataText( itemData, txt ) : CFRelease( txt )
  1202.  
  1203.  
  1204. case _kDataBrowserItemIsActiveProperty:
  1205.  
  1206. if ( itemID mod 5 ) == 3 then err = fn SetDataBrowserItemDataBooleanValue( itemData, _false )
  1207.  
  1208.  
  1209. case _kDataBrowserItemIsEditableProperty:
  1210.  
  1211. err = fn SetDataBrowserItemDataBooleanValue( itemData, _true )
  1212.  
  1213.  
  1214. case _kDataBrowserItemIsContainerProperty:
  1215.  
  1216. err = fn SetDataBrowserItemDataBooleanValue( itemData, fn IsContainer( itemID ) )
  1217.  
  1218.  
  1219. case _kDataBrowserContainerAliasIDProperty:
  1220.  
  1221. if fn IsAlias( itemID ) then err = fn SetDataBrowserItemDataItemID( itemData, 4 )
  1222.  
  1223.  
  1224. case _kDataBrowserItemParentContainerProperty:
  1225. err = fn SetDataBrowserItemDataItemID( itemData, ( itemID-1 ) / _itemsPerContainer )
  1226.  
  1227.  
  1228. case else:
  1229.  
  1230. err = _errDataBrowserPropertyNotSupported
  1231.  
  1232. end select
  1233.  
  1234. xelse
  1235. /*
  1236.      The end user has altered the cell if we come here.
  1237.      For testing with the color column
  1238. */
  1239. select prop
  1240.  
  1241. case  _colorColumnID
  1242. dim as CFStringRef    @ newTxt
  1243.  
  1244. err = fn GetDataBrowserItemDataText( itemData, newTxt )
  1245. err = fn CFStringGetPascalString(newTxt, @s, 256, _kCFStringEncodingMacRoman )
  1246. if newTxt then CFRelease( newTxt )
  1247.  
  1248. s = "Not shown in this demo. Data changed : Item:" + str$( itemID ) + "; Value: " + s
  1249. fn ShowMe( s )
  1250.  
  1251. case else : err = _errDataBrowserPropertyNotSupported
  1252.  
  1253. end select
  1254.  
  1255. end if
  1256.  
  1257. end fn = err
  1258.  
  1259. '~'1
  1260. '~DataBrowser Custom Sorting
  1261. /*
  1262.      This function is called via a callback procedure.
  1263.      Sometimes the DataBrowser doesn't know how to deal with
  1264.      certain data when it needs to sort the list. You can provide
  1265.      a custom sort routine in that scenario.
  1266. */
  1267. clear local fn MyItemComparison( browser as ControlRef, ┬
  1268.                            itemOneID as DataBrowserItemID, ┬
  1269.                            itemTwoID as DataBrowserItemID, ┬
  1270.                          sortProperty as DataBrowserPropertyID)
  1271.  
  1272. dim as SInt16   compareResult
  1273. dim as SInt32   val1, val2
  1274. dim as Str255   s1, s2
  1275. dim as boolean  result
  1276.  
  1277. select sortProperty
  1278.  
  1279. case _flavorColumnID:
  1280.  
  1281. s1 = str#( _flavorListResID, itemOneID mod 5 + 1 )
  1282. s2 = str#( _flavorListResID, itemTwoID mod 5 + 1 )
  1283. compareResult = fn CompareString( s1, s2, _nil )
  1284.  
  1285. select compareResult
  1286. case < 0  : result = _true
  1287. case > 0  : result = _false
  1288. case else : result = fn MyItemComparison( _nil, itemOneID, itemTwoID, _"????" )
  1289. end select
  1290.  
  1291. case _colorColumnID:
  1292.  
  1293. s1 = str#( _colorListResID, itemOneID mod 5 + 1 )
  1294. s2 = str#( _colorListResID, itemTwoID mod 5 + 1 )
  1295. compareResult = fn CompareString( s1, s2, _nil )
  1296.  
  1297. select compareResult
  1298. case < 0  : result = _true
  1299. case > 0  : result = _false
  1300. case else : result = fn MyItemComparison( _nil, itemOneID, itemTwoID, _"foo " )
  1301. end select
  1302.  
  1303. case _progressColumnID:
  1304.  
  1305. val1 = (itemOneID mod 5) * 20
  1306. val2 = (itemTwoID mod 5) * 20
  1307.  
  1308. select
  1309. case val1 < val2 : result = _true
  1310. case val1 > val2 : result = _false
  1311. case else        : result = fn MyItemComparison( _nil, itemOneID, itemTwoID, _"????" )
  1312. end select
  1313.  
  1314. case else: result = ( itemOneID < itemTwoID )
  1315.  
  1316. end select
  1317.  
  1318. end fn = result
  1319.  
  1320. '~'1
  1321. '~DataBrowser Notification
  1322. /*
  1323.      This function is invoked by a callback procedure. The DataBrowser
  1324.      control can notify the program of interesting things happening.
  1325.  
  1326.           Constant Name                                  Description
  1327.      _kDataBrowserItemAdded             The specified item has been added to the browser.
  1328.      _kDataBrowserItemRemoved           The specified item has been removed from the browser.
  1329.      _kDataBrowserEditStarted           Starting an EditText session for specified item.
  1330.      _kDataBrowserEditStopped           Stopping an EditText session for specified item.
  1331.      _kDataBrowserItemSelected          Item has just been added to the selection set.
  1332.      _kDataBrowserItemDeselected        Item has just been removed from the selection set.
  1333.      _kDataBrowserItemDoubleClicked     The user double clicked on an item.
  1334.      _kDataBrowserContainerOpened       Container has been opened.
  1335.      _kDataBrowserContainerClosing      Container is about to close.
  1336.      _kDataBrowserContainerClosed       Container has been closed.
  1337.      _kDataBrowserContainerSorting      Container is about to be sorted (lock any volatile properties).
  1338.      _kDataBrowserContainerSorted       Container has been sorted (you may release any property locks).
  1339.      _kDataBrowserTargetChanged         The target has changed to the specified item.
  1340.      _kDataBrowserUserStateChanged      The user has reformatted the view for the target.
  1341.      _kDataBrowserSelectionSetChanged   The selection set has been modified (net result may be the same).
  1342. */
  1343. clear local fn MyItemNotification( browser as ControlRef, itemID as DataBrowserItemID, message as DataBrowserItemNotification )
  1344.  
  1345. dim as OSStatus            err
  1346. dim as UInt32              i
  1347. dim as DataBrowserItemID   myItems(_itemsPerContainer)
  1348. dim as Boolean           @ variableHeightRows
  1349.  
  1350. select message
  1351.  
  1352. //err = fn SetDataBrowserItemDataButtonValue( itemData, _kThemeButtonOn )
  1353.  
  1354. //     Rem'd out in the Apple demo
  1355. //case _kDataBrowserItemSelected:
  1356.  
  1357. //dim as Handle  @ h
  1358. //dim as UInt32   numSelectedItems
  1359.  
  1360. //h = fn NewHandle( 0 )
  1361. //err = fn GetDataBrowserItems( browser,  _kDataBrowserNoItem, true, _kDataBrowserItemIsSelected, h )
  1362. //numSelectedItems = fn GetHandleSize( h ) / sizeof(DataBrowserItemID)
  1363.  
  1364. case _kDataBrowserContainerOpened: // Generate some valid itemIDs
  1365.  
  1366. for i = 0 to _itemsPerContainer - 1
  1367. myItems(i) = itemID * _itemsPerContainer + i + 1
  1368. next
  1369.  
  1370. err = fn AddDataBrowserItems( browser, itemID, _itemsPerContainer, myItems(0), _indexColumnID )
  1371.  
  1372. // Set up variable height rows
  1373. err = fn GetDataBrowserTableViewGeometry( browser, #_nil, variableHeightRows )
  1374.  
  1375. long if variableHeightRows
  1376. for i = 0 to _itemsPerContainer - 1
  1377. err = fn SetDataBrowserTableViewItemRowHeight( browser, myItems(i), 20 + ( myItems(i) - 1 ) mod 10 * 3 )
  1378. next
  1379. end if
  1380.  
  1381. case _kDataBrowserSelectionSetChanged:
  1382. DrawOneControl(gPlacard)
  1383.  
  1384. end select
  1385.  
  1386. end fn
  1387.  
  1388. '~'1
  1389. '~DataBrowser Help Tags
  1390. /*
  1391.      This function is invoked by a callback procedure when it is
  1392.      time for the program to provide help content for help tags.
  1393. */
  1394. clear local fn MyItemHelpContent( browser as ControlRef, item as DataBrowserItemID, prop as DataBrowserPropertyID, inRequest as HMContentRequest, outContentProvided as .HMContentProvidedType, ioHelpContent as .HMHelpContentRec )
  1395.  
  1396. dim as HMHelpContent helpContent // temporary HMHelpContent record
  1397. dim as Boolean       helpContentProperty
  1398.  
  1399. helpContentProperty = ( prop == _flavorColumnID ) or ( prop == _kDataBrowserItemSelfIdentityProperty )
  1400.  
  1401. long if ( inRequest == _kHMSupplyContent and ( item != _kDataBrowserNoItem ) and helpContentProperty )
  1402. outContentProvided.nil% = _kHMContentProvided
  1403. helpContent.contentType = _kHMStringResContent
  1404. helpContent.tagStringRes.hmmIndex = item mod 5 + 1
  1405. helpContent.tagStringRes.hmmResID = _commentListResID
  1406. //ioHelpContent.content[_kHMMaximumContentIndex] = helpContent
  1407. ioHelpContent.content[0] = helpContent
  1408. end if
  1409.  
  1410. end fn
  1411.  
  1412. '~'1
  1413. '~DataBrowser Contextual Menu
  1414. /*
  1415.      This function is called via a callback procedure when the
  1416.      DataBrowser needs a contextual menu to display.
  1417. */
  1418. clear local fn MyGetContextualMenu( browser as ControlRef, @contextualMenu as .MenuRef, helpType as .UInt32, @helpItemString as .CFStringRef, selection as .AEDesc )
  1419.  
  1420. helpItemString.nil& = fn CFStringCreateWithPascalString( fn CFAllocatorGetDefault, "Testing 1-2-3", _kCFStringEncodingMacRoman)
  1421. helpType.nil&       = _kCMHelpItemOtherHelp
  1422.  
  1423. long if gContextualMenu
  1424. contextualMenu.nil& = gContextualMenu
  1425. xelse
  1426. contextualMenu.nil& = fn GetMenu( _contextualMenuResID )
  1427. InsertMenu( contextualMenu.nil&, -1 )
  1428. end if
  1429.  
  1430. end fn
  1431.  
  1432. '~'1
  1433. /*
  1434.      This function is called by the DataBrowser via a callback
  1435.      routine when the end user has chosen an item in a contextual menu.
  1436. */
  1437. clear local fn MySelectContextualMenu( browser as ControlRef, contextualMenu as MenuRef, selectionType as UInt32, menuID as SInt16, menuItem as MenuItemIndex )
  1438.  
  1439. dim as str255 s
  1440.  
  1441. GetMenuItemText( contextualMenu, menuItem, s )
  1442. long if gContextualMenu = _nil
  1443. DeleteMenu( _contextualMenuResID )
  1444. DisposeMenu( contextualMenu )
  1445. end if
  1446.  
  1447. fn ShowMe( s )
  1448.  
  1449. end fn
  1450.  
  1451. '~DataBrowser Placard Drawing
  1452. '~'1
  1453. /*
  1454.      This function is called by a callback procedure installed
  1455.      in a placard control, so that it updates itself at the
  1456.      right location on screen with the right info.
  1457. */
  1458. clear local fn MyPlacardDraw( c as ControlRef, dummy as SInt16 )
  1459.  
  1460. dim as OSStatus     err
  1461. dim as ControlRef   browser
  1462. dim as Str255       s, placardStr
  1463. dim as UInt32     @ numSelectedItems
  1464. dim as Rect         r
  1465.  
  1466. browser = fn GetControlReference( c )
  1467. s = " Items Selected"
  1468. long if browser
  1469. GetControlBounds( browser, r )
  1470. r.top   = r.bottom - 15
  1471. r.right = r.left + 100
  1472.  
  1473. err = fn GetDataBrowserItemCount( browser, _kDataBrowserNoItem, _true, _kDataBrowserItemIsSelected, numSelectedItems )
  1474. NumToString( numSelectedItems, placardStr )
  1475. BlockMoveData( @s[1], @placardStr[placardStr[0]+1], s[0] )
  1476. placardStr[0] += s[0]
  1477.  
  1478. long if fn IsControlActive( c )
  1479. err = fn DrawThemePlacard( r, _kThemeStateActive )
  1480. err = fn SetThemeTextColor( _kThemeTextColorPlacardActive, 8, _true )
  1481. xelse
  1482. err = fn DrawThemePlacard( r, _kThemeStateInactive )
  1483. err = fn SetThemeTextColor( _kThemeTextColorPlacardInactive, 8, _true )
  1484. end if
  1485.  
  1486. err = fn UseThemeFont( _kThemeSmallSystemFont, _smSystemScript )
  1487. MoveTo( r.left + (r.right - r.left)/2 - fn StringWidth( placardStr )/2, r.bottom - 4)
  1488. DrawString( placardStr )
  1489. end if
  1490.  
  1491. end fn
  1492.  
  1493. '~';
  1494. '~--------
  1495. '~DataBrowser Installing
  1496. /*
  1497.      After creating the DataBrowser, you need to configure it.
  1498.      That is to say to define columns and their properties.
  1499.      Here are the tcolumn types you can use:
  1500.  
  1501.           constant names                 cell's contents are set with
  1502.      _kDataBrowserCustomType        No associated data, must use custom callbacks
  1503.      _kDataBrowserIconType          IconRef, IconTransformType, RGBColor 
  1504.      _kDataBrowserTextType          CFStringRef
  1505.      _kDataBrowserDateTimeType      DateTime or LongDateTime
  1506.      _kDataBrowserSliderType        Min, Max, Value
  1507.      _kDataBrowserCheckboxType      ThemeButtonValue
  1508.      _kDataBrowserProgressBarType   Min, Max, Value
  1509.      _kDataBrowserRelevanceRankType Min, Max, Value
  1510.      _kDataBrowserPopupMenuType     MenuRef, Value
  1511.      _kDataBrowserIconAndTextType   IconRef, CFStringRef, etc 
  1512.  
  1513. */
  1514. clear local fn ConfigureDataBrowser( browser as ControlRef )
  1515.  
  1516. dim as OSStatus                       err
  1517. dim as str15                          cr
  1518. dim as Rect                           insR
  1519. dim as DataBrowserListViewColumnDesc  colDesc
  1520. dim as DataBrowserViewStyle         @ viewStyle
  1521.  
  1522. cr = chr$( 13 )
  1523.  
  1524. #if ndef _kDataBrowserListViewAppendColumn
  1525. _kDataBrowserListViewAppendColumn = 4294967295 // _ULONG_MAX defined in ANSI Headers (limits.h)
  1526. #endif
  1527.  
  1528. err = fn GetDataBrowserViewStyle( browser, viewStyle )
  1529. err = fn GetDataBrowserScrollBarInset( browser, insR )
  1530. insR.right = _scrollBarWidth - 1
  1531. err = fn SetDataBrowserScrollBarInset( browser, insR )
  1532.  
  1533. select viewStyle
  1534.  
  1535. case _kDataBrowserListView:
  1536.  
  1537. colDesc.headerBtnDesc.titleOffset        = 0
  1538. colDesc.headerBtnDesc.version            = _kDataBrowserListViewLatestHeaderDesc
  1539. colDesc.headerBtnDesc.btnFontStyle.flags = _kControlUseFontMask_kControlUseJustMask
  1540. colDesc.headerBtnDesc.btnContentInfo.contentType = _kControlNoContent
  1541. err = fn GetIconRef( _kOnSystemDisk, _kSystemIconsCreator, _kGenericFolderIcon, colDesc.headerBtnDesc.btnContentInfo.iconRef )
  1542.  
  1543. // Add the checkbox column
  1544. colDesc.propertyDesc.propertyID    = _checkboxColumnID
  1545. colDesc.propertyDesc.propertyType  = _kDataBrowserCheckboxType
  1546. colDesc.propertyDesc.propertyFlags = _kDataBrowserPropertyIsMutable _kDataBrowserDefaultPropertyFlags
  1547. colDesc.headerBtnDesc.minimumWidth = 30
  1548. colDesc.headerBtnDesc.maximumWidth = 30
  1549. colDesc.headerBtnDesc.btnFontStyle.just  = _teCenter
  1550. colDesc.headerBtnDesc.btnFontStyle.font  = _kControlFontViewSystemFont
  1551. colDesc.headerBtnDesc.btnFontStyle.style = _normal
  1552. colDesc.headerBtnDesc.titleString = fn CFStringCreateWithPascalString( fn CFAllocatorGetDefault, cr, _kCFStringEncodingMacRoman )
  1553. err = fn AddDataBrowserListViewColumn( browser, colDesc, _kDataBrowserListViewAppendColumn )
  1554.  
  1555. // Add the Flavor column
  1556. colDesc.propertyDesc.propertyID    = _flavorColumnID
  1557. colDesc.propertyDesc.propertyType  = _kDataBrowserIconAndTextType
  1558. colDesc.propertyDesc.propertyFlags = _kDataBrowserPropertyIsMutable_kDataBrowserListViewSelectionColumn_kDataBrowserListViewDefaultColumnFlags
  1559. colDesc.headerBtnDesc.btnContentInfo.contentType = _kControlContentIconRef
  1560. colDesc.headerBtnDesc.minimumWidth      = 0
  1561. colDesc.headerBtnDesc.maximumWidth      = 280
  1562. colDesc.headerBtnDesc.btnFontStyle.just = _teFlushDefault
  1563. colDesc.headerBtnDesc.titleString = fn CFStringCreateWithPascalString( fn CFAllocatorGetDefault(), "Flavor", _kCFStringEncodingMacRoman )
  1564. err = fn AddDataBrowserListViewColumn( browser, colDesc, _kDataBrowserListViewAppendColumn )
  1565.  
  1566. // Add the icon column
  1567. colDesc.propertyDesc.propertyID    = _iconOnlyColumnID
  1568. colDesc.propertyDesc.propertyType  = _kDataBrowserIconType
  1569. colDesc.propertyDesc.propertyFlags = _kDataBrowserListViewSelectionColumn_kDataBrowserListViewDefaultColumnFlags
  1570. colDesc.headerBtnDesc.btnContentInfo.contentType = _kControlContentIconRef
  1571. colDesc.headerBtnDesc.minimumWidth      = 0
  1572. colDesc.headerBtnDesc.maximumWidth      = 100
  1573. colDesc.headerBtnDesc.btnFontStyle.just = _teCenter
  1574. colDesc.headerBtnDesc.titleString       = _nil
  1575. err = fn AddDataBrowserListViewColumn( browser, colDesc, _kDataBrowserListViewAppendColumn )
  1576.  
  1577. // Add the Index column
  1578. colDesc.headerBtnDesc.maximumWidth      = 120
  1579. colDesc.propertyDesc.propertyID         = _indexColumnID
  1580. colDesc.propertyDesc.propertyType       = _kDataBrowserTextType
  1581. colDesc.headerBtnDesc.btnFontStyle.just = _teCenter
  1582. colDesc.headerBtnDesc.titleString       = fn CFStringCreateWithPascalString( fn CFAllocatorGetDefault, "Index", _kCFStringEncodingMacRoman )
  1583. err = fn AddDataBrowserListViewColumn( browser, colDesc, _kDataBrowserListViewAppendColumn)
  1584.  
  1585. // Add the Color column
  1586. colDesc.propertyDesc.propertyID         = _colorColumnID
  1587. colDesc.headerBtnDesc.btnFontStyle.just = _teFlushRight
  1588. colDesc.propertyDesc.propertyFlags      = _kDataBrowserPropertyIsMutable _kDataBrowserListViewDefaultColumnFlags
  1589. colDesc.headerBtnDesc.titleString       = fn CFStringCreateWithPascalString( fn CFAllocatorGetDefault(), "Color", _kCFStringEncodingMacRoman )
  1590. err = fn AddDataBrowserListViewColumn( browser, colDesc, _kDataBrowserListViewAppendColumn)
  1591.  
  1592. // Add the ItemID column
  1593. colDesc.propertyDesc.propertyID         = _itemIDColumnID
  1594. colDesc.propertyDesc.propertyFlags      = _kDataBrowserListViewDefaultColumnFlags
  1595. colDesc.headerBtnDesc.btnFontStyle.just = _teFlushDefault
  1596. colDesc.headerBtnDesc.titleString       = fn CFStringCreateWithPascalString( fn CFAllocatorGetDefault(), "ItemID", _kCFStringEncodingMacRoman )
  1597. err = fn AddDataBrowserListViewColumn( browser, colDesc, _kDataBrowserListViewAppendColumn)
  1598.  
  1599. // Add the slider column
  1600. colDesc.propertyDesc.propertyID         = _sliderColumnID
  1601. colDesc.headerBtnDesc.btnFontStyle.just = _teCenter
  1602. colDesc.propertyDesc.propertyType       = _kDataBrowserSliderType
  1603. colDesc.propertyDesc.propertyFlags      = _kDataBrowserSliderPlainThumb _kDataBrowserPropertyIsMutable _kDataBrowserListViewDefaultColumnFlags
  1604. colDesc.headerBtnDesc.minimumWidth      = 80
  1605. colDesc.headerBtnDesc.maximumWidth      = 150
  1606. colDesc.headerBtnDesc.btnContentInfo.contentType = _kControlContentTextOnly
  1607. colDesc.headerBtnDesc.titleString = fn CFStringCreateWithPascalString(fn CFAllocatorGetDefault, "Slider", _kCFStringEncodingMacRoman )
  1608. err = fn AddDataBrowserListViewColumn( browser, colDesc, _kDataBrowserListViewAppendColumn )
  1609.   
  1610. // Add the progress bar column
  1611. colDesc.propertyDesc.propertyID         = _progressColumnID
  1612. colDesc.headerBtnDesc.btnFontStyle.just = _teFlushDefault
  1613. colDesc.propertyDesc.propertyType       = _kDataBrowserRelevanceRankType
  1614. colDesc.propertyDesc.propertyFlags      = _kDataBrowserListViewDefaultColumnFlags
  1615. colDesc.headerBtnDesc.btnContentInfo.contentType = _kControlContentTextOnly
  1616. colDesc.headerBtnDesc.titleString       = fn CFStringCreateWithPascalString(fn CFAllocatorGetDefault, "Relevance Rank", _kCFStringEncodingMacRoman )
  1617. err = fn AddDataBrowserListViewColumn( browser, colDesc, _kDataBrowserListViewAppendColumn )
  1618.  
  1619. // Add date/time column
  1620. colDesc.propertyDesc.propertyID         = _dateTimeColumnID
  1621. colDesc.headerBtnDesc.btnFontStyle.just = _teFlushLeft
  1622. colDesc.propertyDesc.propertyType       = _kDataBrowserDateTimeType
  1623. colDesc.propertyDesc.propertyFlags      = _kDataBrowserListViewSelectionColumn_kDataBrowserListViewDefaultColumnFlags
  1624. colDesc.headerBtnDesc.minimumWidth      = 50
  1625. colDesc.headerBtnDesc.maximumWidth      = 200
  1626. colDesc.headerBtnDesc.titleString       = fn CFStringCreateWithPascalString( fn CFAllocatorGetDefault, "Date/Time", _kCFStringEncodingMacRoman )
  1627. err = fn AddDataBrowserListViewColumn( browser, colDesc, _kDataBrowserListViewAppendColumn )
  1628.  
  1629. // Add column 8
  1630. colDesc.propertyDesc.propertyID    = _popupMenuColumnID
  1631. colDesc.propertyDesc.propertyType  = _kDataBrowserPopupMenuType
  1632. colDesc.propertyDesc.propertyFlags = _kDataBrowserPropertyIsMutable_kDataBrowserListViewDefaultColumnFlags
  1633. colDesc.headerBtnDesc.titleString  = fn CFStringCreateWithPascalString( fn CFAllocatorGetDefault, "Popup menu", _kCFStringEncodingMacRoman )
  1634. err = fn AddDataBrowserListViewColumn( browser, colDesc, _kDataBrowserListViewAppendColumn )
  1635.  
  1636. // Finish formatting the table
  1637. /*
  1638. err = fn SetDataBrowserTableViewRowHeight( browser, 11 )
  1639. err = fn SetDataBrowserSortProperty( browser, _flavorColumnID )
  1640. */
  1641. err = fn SetDataBrowserListViewDisclosureColumn( browser, _flavorColumnID, _false )
  1642. err = fn ReleaseIconRef( colDesc.headerBtnDesc.btnContentInfo.iconRef )
  1643.  
  1644. case _kDataBrowserColumnView:
  1645. /*
  1646. dim as DataBrowserItemID path(1)
  1647. path(0) = 48 : path(1) = 485
  1648. err = fn SetDataBrowserColumnViewPath(browser, 2, @path(0))
  1649. err = fn SetDataBrowserTarget(browser, 50695)
  1650. */
  1651. end select
  1652.  
  1653. // fn RestoreUserState
  1654. end fn
  1655.  
  1656. '~';
  1657. /*
  1658.      This function creates the DataBrowser
  1659. */
  1660. clear local fn CreateDataBrowser( w as WindowRef )
  1661.  
  1662. dim as Rect         r
  1663. dim as ControlRef @ browser
  1664. dim as Boolean    @ frameAndFocus
  1665.  
  1666. // Create a DataBrowser
  1667. r.top   =   0 : r.left   =   0
  1668. r.right = 400 : r.bottom = 200
  1669. long if fn CreateDataBrowserControl( w, r, _kDataBrowserListView, browser ) = _noErr
  1670. // Turn off DB's focus frame
  1671. long if fn SetControlData( browser, _kControlNoPart, _kControlDataBrowserIncludesFrameAndFocusTag, sizeof(frameAndFocus), frameAndFocus )
  1672. end if
  1673. end if
  1674.  
  1675. end fn = browser
  1676.  
  1677. '~';
  1678. /*
  1679.      This function sets all the callback procedures that the
  1680.      DataBrowser will use to communicate with the program.
  1681. */
  1682. clear local fn InstallDataBrowserCallbacks( browser as ControlRef )
  1683.  
  1684. dim as OSStatus               err
  1685. dim as DataBrowserCallbacks @ myCallbacks
  1686.  
  1687. //Use latest layout and callback signatures
  1688. myCallbacks.version = _kDataBrowserLatestCallbacks
  1689. err = fn InitDataBrowserCallbacks( myCallbacks )
  1690.  
  1691. myCallbacks.u.v1.itemDataCallback             = fn NewDataBrowserItemDataUPP            ([proc "GetSetItemDataProc"       + _FBprocToProcPtrOffset])
  1692. myCallbacks.u.v1.itemCompareCallback          = fn NewDataBrowserItemCompareUPP         ([proc "ItemComparisonProc"       + _FBprocToProcPtrOffset])
  1693. myCallbacks.u.v1.itemNotificationCallback     = fn NewDataBrowserItemNotificationUPP    ([proc "ItemNotificationProc"     + _FBprocToProcPtrOffset])
  1694. myCallbacks.u.v1.acceptDragCallback           = fn NewDataBrowserAcceptDragUPP          ([proc "AcceptDragProc"           + _FBprocToProcPtrOffset])
  1695. myCallbacks.u.v1.receiveDragCallback          = fn NewDataBrowserReceiveDragUPP         ([proc "ReceiveDragProc"          + _FBprocToProcPtrOffset])
  1696. myCallbacks.u.v1.addDragItemCallback          = fn NewDataBrowserAddDragItemUPP         ([proc "AddDragItemProc"          + _FBprocToProcPtrOffset])
  1697. myCallbacks.u.v1.itemHelpContentCallback      = fn NewDataBrowserItemHelpContentUPP     ([proc "ItemHelpContentProc"      + _FBprocToProcPtrOffset])
  1698. myCallbacks.u.v1.getContextualMenuCallback    = fn NewDataBrowserGetContextualMenuUPP   ([proc "GetContextualMenuProc"    + _FBprocToProcPtrOffset])
  1699. myCallbacks.u.v1.selectContextualMenuCallback = fn NewDataBrowserSelectContextualMenuUPP([proc "SelectContextualMenuProc" + _FBprocToProcPtrOffset])
  1700.  
  1701. err =  fn SetDataBrowserCallbacks( browser, myCallbacks )
  1702.  
  1703. end fn
  1704.  
  1705. '~----
  1706. '~Menu Handling
  1707. '~';
  1708. /*
  1709.      This function update the state of a few menu items. Depending
  1710.      on certain conditions it enables/disables and checks/unchecks
  1711.      the relevant menu items.
  1712. */
  1713. clear local fn UpdateDataBrowserCommand( browser as ControlRef, cmd as .HICommand )
  1714.  
  1715. dim as OSStatus               result, err
  1716. dim as DataBrowserViewStyle @ viewStyle
  1717. dim as Boolean                commandIsEnabled
  1718.  
  1719. commandIsEnabled = _true
  1720.  
  1721. select cmd.commandID
  1722.  
  1723. case _showPlacardCmd:
  1724.  
  1725. CheckMenuItem( cmd.menu.menuRef, cmd.menu.menuItemIndex, gPlacard != _nil )
  1726.  
  1727. case _kHICommandCut, _kHICommandUndo, _kHICommandRedo, _kHICommandCopy, _kHICommandPaste, _kHICommandClear, _kHICommandSelectAll:
  1728.  
  1729. commandIsEnabled = fn EnableDataBrowserEditCommand( browser, cmd.commandID )
  1730.  
  1731. case _customizeViewCmd:
  1732.  
  1733. err = fn GetDataBrowserViewStyle( browser, viewStyle )
  1734. commandIsEnabled = ( viewStyle == _kDataBrowserListView )
  1735.  
  1736. CheckMenuItem( cmd.menu.menuRef, 1, ( commandIsEnabled ) )
  1737. CheckMenuItem( cmd.menu.menuRef, 3, not( commandIsEnabled ) )
  1738.  
  1739. case else : result = _eventNotHandledErr
  1740.  
  1741. end select
  1742.  
  1743. long if result == _noErr
  1744. long if commandIsEnabled
  1745. EnableMenuCommand( cmd.menu.menuRef, cmd.commandID )
  1746. xelse
  1747. DisableMenuCommand( cmd.menu.menuRef, cmd.commandID )
  1748. end if
  1749. end if
  1750.  
  1751. end fn = result
  1752.  
  1753. '~';
  1754. /*
  1755.      This function is similar to a menu handler, it deals
  1756.      with the end user choice in the menubar.
  1757. */
  1758. clear local fn HandleDataBrowserCommand( inBrowser as ControlRef, cmd as .HICommand )
  1759.  
  1760. dim as OSStatus               result, err
  1761. dim as Rect                   sBarInset, placardBounds
  1762. dim as ControlRef           @ browser
  1763. dim as DataBrowserViewStyle @ view
  1764. dim as proc                 @ drawProc
  1765.  
  1766. browser = inBrowser// for RAM variable
  1767.  
  1768. select cmd.commandID
  1769.  
  1770. case _showPlacardCmd:
  1771.  
  1772. err = fn GetDataBrowserScrollBarInset( browser, sBarInset )
  1773.  
  1774. long if gPlacard
  1775. GetControlBounds( gPlacard, placardBounds )
  1776. DisposeControl( gPlacard ) : gPlacard = _nil
  1777. sBarInset.left -= placardBounds.right - placardBounds.left
  1778. xelse
  1779. GetControlBounds( browser, placardBounds )
  1780. placardBounds.top   = placardBounds.bottom - 15
  1781. placardBounds.right = placardBounds.left + 100
  1782.  
  1783. err = fn CreateUserPaneControl( fn GetControlOwner( browser ), placardBounds, 0, gPlacard )
  1784. long if gPlacard
  1785. err = fn SetControlVisibility( gPlacard, _true, _true )
  1786. SetControlReference( gPlacard, browser )
  1787. err = fn EmbedControl( gPlacard, browser )
  1788. sBarInset.left += placardBounds.right - placardBounds.left
  1789.  
  1790. drawProc = fn NewControlUserPaneDrawUPP( [proc "PlacardDrawProc" + _FBprocToProcPtrOffset] )
  1791. if fn SetControlData( gPlacard, _kControlNoPart, _kControlUserPaneDrawProcTag, sizeof(drawProc), drawProc ) then exit case
  1792. DrawOneControl( gPlacard )
  1793. end if
  1794. end if
  1795. err = fn SetDataBrowserScrollBarInset( browser, sBarInset )
  1796.  
  1797. // Rem'd out in the original Apple example file
  1798. case _kHICommandCut, _kHICommandUndo, _kHICommandRedo, _kHICommandCopy, _kHICommandPaste, _kHICommandClear, _kHICommandSelectAll:
  1799.  
  1800. err = fn ExecuteDataBrowserEditCommand( browser, cmd.commandID )
  1801.  
  1802. case _kDataBrowserListView, _kDataBrowserColumnView:
  1803.  
  1804. err = fn GetDataBrowserViewStyle( browser, view )
  1805.  
  1806. long if ( view != cmd.commandID )
  1807. err = fn SetDataBrowserViewStyle( browser, cmd.commandID )
  1808. fn ConfigureDataBrowser( browser )
  1809. end if
  1810.  
  1811. case _DataBrowserSettingsCmd   : fn SetupCustomizer( browser, _settingsDLOGResID )
  1812.  
  1813. case _customizeViewCmd         : fn SetupCustomizer( browser, _customizeDLOGResID )
  1814.  
  1815. case else                      : result = _eventNotHandledErr
  1816.  
  1817. end select
  1818.  
  1819. end fn = result
  1820.  
  1821. '~';
  1822. /*
  1823.      This function simply gets and draw the menubar in resource
  1824. */
  1825. clear local fn InstallStandardMenuBar( draw as Boolean )
  1826.  
  1827. dim as Handle menuBar
  1828.  
  1829. menuBar = fn GetNewMBar( 128 )
  1830. if menuBar then SetMenuBar( menuBar )
  1831. if draw    then DrawMenuBar
  1832.  
  1833. end fn = _noErr
  1834.  
  1835.  
  1836. '~';
  1837. '~Event Handling
  1838. /*
  1839.      This function will process the events the window can handle
  1840. */
  1841. clear local fn HandleWindowCommand( inEvent as EventRef )
  1842.  
  1843. dim as ControlRef    browser
  1844. dim as HICommand     cmd
  1845. dim as OSStatus      result,err
  1846. dim as WindowRef   @ w
  1847. dim as EventRef    @ evt
  1848.  
  1849. result = _eventNotHandledErr
  1850. err    = fn GetEventParameter( inEvent, _kEventParamDirectObject, _typeHICommand, #_nil, sizeof(cmd), #_nil, @cmd )
  1851. w      = fn GetUserFocusWindow
  1852.  
  1853. browser = fn GetDataBrowserFromWindow( w )
  1854.  
  1855. select fn GetEventKind( inEvent )
  1856.  
  1857. case _kEventCommandProcess:
  1858.  
  1859. long if ( cmd.commandID == _closeWindowCmd )
  1860. dim as EventTime   eT// Robert Purves' fix ( 8/05/03 }
  1861. eT     = fn GetCurrentEventTime
  1862. result = _noErr
  1863. err    = fn CreateEvent( _nil, _kEventClassWindow, _kEventWindowClose, eT, _kEventAttributeUserEvent, @evt )
  1864. err    = fn SetEventParameter( evt, _kEventParamDirectObject, _typeWindowRef, sizeof(w), w )
  1865. if err == _noErr then fn SendEventToWindow( evt, fn GetUserFocusWindow )
  1866. xelse
  1867. result = fn HandleDataBrowserCommand( browser, cmd )
  1868. end if
  1869.  
  1870. case _kEventCommandUpdateStatus:
  1871.  
  1872. result = fn UpdateDataBrowserCommand( browser, cmd )
  1873.  
  1874. end select
  1875.  
  1876. end fn = result
  1877.  
  1878. '~'1
  1879. /*
  1880.      This function will handle the events targetted at our
  1881.      two dialog windows for customization.
  1882. */
  1883. clear local fn MyDialogEventHandler( EventHandlerCallRef as ptr, inEvent as EventRef, void as ptr )
  1884.  
  1885. dim as OSStatus     result, err
  1886. dim as UInt16       customizerID
  1887. dim as ControlRef   browser, @ c
  1888. dim as DialogRef  @ dlog
  1889. dim as WindowRef  @ w
  1890. dim as proc       @ eventHandler
  1891.  
  1892. result = _eventNotHandledErr
  1893.  
  1894. select fn GetEventClass( inEvent )
  1895.  
  1896. case _kEventClassCommand:
  1897.  
  1898. result = fn HandleWindowCommand( inEvent )
  1899.  
  1900. case _kEventClassControl:
  1901.  
  1902. result = _noErr
  1903. err = fn GetEventParameter( inEvent, _kEventParamDirectObject, _typeControlRef, #_nil, sizeof(c), #_nil, c )
  1904. fn HandleCustomizerControl( c )
  1905.  
  1906. case _kEventClassWindow:
  1907.  
  1908. err  = fn GetEventParameter( inEvent, _kEventParamDirectObject, _typeWindowRef, #_nil, sizeof(w), #_nil, w )
  1909. dlog = fn GetDialogFromWindow( w )
  1910.  
  1911. select fn GetEventKind( inEvent )
  1912.  
  1913. case _kEventWindowClose:
  1914.  
  1915. result       = _noErr
  1916. browser      = fn GetDataBrowserFromWindow( w )
  1917. customizerID = fn GetCustomerID( w )
  1918. err = fn GetWindowProperty( w, _myCreator, _myEventHandler, sizeof(eventHandler), #_nil, eventHandler )
  1919. if eventHandler then DisposeEventHandlerUPP( eventHandler )
  1920. DisposeDialog( dlog ) : dlog = _nil
  1921.  
  1922. err = fn SetControlProperty( browser, _myCreator, customizerID, sizeof(dlog), dlog )
  1923. end select
  1924.  
  1925. end select
  1926.  
  1927. end fn = result
  1928.  
  1929. '~'1
  1930. /*
  1931.      This function is called by a callback procedure installed
  1932.      with the main window. It is a bit similar to a traditional
  1933.      dialog event handler except that it is specific to this window.
  1934. */
  1935. clear local fn MyWindowEventHandler( EventHandlerCallRef as ptr, inEvent as EventRef, void as ptr )
  1936.  
  1937. dim as OSStatus    result, err
  1938. dim as ControlRef  browser
  1939. dim as DialogRef   customizer
  1940. dim as UInt16      IDs(1)
  1941. dim as UInt16      i, @ ID
  1942. dim as WindowRef @ w
  1943. dim as Rect        r
  1944.  
  1945. result = _noErr
  1946.  
  1947. select fn GetEventClass( inEvent )
  1948.  
  1949. case _kEventClassCommand:
  1950.  
  1951. result = fn HandleWindowCommand( inEvent )
  1952.  
  1953. case _kEventClassWindow:
  1954.  
  1955. err = fn GetEventParameter( inEvent, _kEventParamDirectObject, _typeWindowRef, #_nil, sizeof(w), #_nil, w )
  1956.  
  1957. select fn GetEventKind( inEvent )
  1958.  
  1959. case _kEventWindowClose:
  1960.  
  1961. browser = fn GetDataBrowserFromWindow( w )
  1962. IDs(0)  = _settingsDLOGResID
  1963. IDs(1)  = _customizeDLOGResID
  1964.  
  1965. for i = 0 to 1
  1966. ID = IDs(i)
  1967. customizer = fn GetCustomizer( browser, ID )
  1968. if customizer then DisposeDialog( customizer )
  1969. next
  1970.  
  1971. DisposeWindow( w )
  1972. QuitApplicationEventLoop
  1973.  
  1974. case _kEventWindowBoundsChanged:
  1975.  
  1976. browser = fn GetDataBrowserFromWindow( w )
  1977.  
  1978. err = fn GetPortBounds( fn GetWindowPort( w ), r )
  1979. // err = fn GetWindowBounds( w, _kWindowContentRgn, r )
  1980. SizeControl( browser, r.right - r.left, r.bottom - r.top )
  1981.  
  1982. #if def _typeQDPoint
  1983.  
  1984. case _kEventWindowGetIdealSize:
  1985.  
  1986. dim as Rect     bestRect
  1987. dim as SInt16 @ baseLine
  1988. dim as Point  @ idealDimensions
  1989.  
  1990. err = fn GetBestControlRect( fn GetDataBrowserFromWindow( w ), bestRect, baseLine )
  1991. err = fn SetEventParameter( inEvent, _kEventParamDimensions, _typeQDPoint, sizeof(idealDimensions), idealDimensions )
  1992.  
  1993. case _kEventWindowGetClickActivation:
  1994.  
  1995. dim as Point                 @ mousePt
  1996. dim as UInt32                @ modifiers
  1997. dim as ClickActivationResult @ activation
  1998.  
  1999. err = fn GetEventParameter( inEvent, _kEventParamMouseLocation, _typeQDPoint, #_nil, sizeof(mousePt)  , #_nil, mousePt )
  2000. err = fn GetEventParameter( inEvent, _kEventParamKeyModifiers , _typeUInt32 , #_nil, sizeof(modifiers), #_nil, modifiers )
  2001. err = fn GetControlClickActivation( fn GetDataBrowserFromWindow( w ), mousePt, modifiers, activation )
  2002. err = fn SetEventParameter( inEvent, _kEventParamClickActivation, _typeClickActivationResult, sizeof(activation), activation )
  2003.  
  2004. #endif // defined(typeQDPoint)
  2005.  
  2006. case _kEventWindowContextualMenuSelect:
  2007.  
  2008. case else
  2009.  
  2010. result = _eventNotHandledErr
  2011.  
  2012. end select
  2013.  
  2014. case else
  2015. result = _eventNotHandledErr
  2016.  
  2017. end select
  2018.  
  2019. end fn = result
  2020.  
  2021.  
  2022. '~';
  2023. '~Program Setup
  2024. /*
  2025.      This function is called at startup to setup a few globals.
  2026.      
  2027. */
  2028. clear local fn SetupGlobals
  2029.  
  2030. dim as IconRef  @ aliasBadgeIcon
  2031. dim as OSStatus   err
  2032.  
  2033. // getting our menu from resource
  2034. gContextualMenu = fn GetMenu( _contextualMenuResID ) : InsertMenu( gContextualMenu, -1 )
  2035.  
  2036. // getting three icons that are stored in an array
  2037. err = fn GetIconRef( _kOnSystemDisk, _kSystemIconsCreator, _kGenericFolderIcon  , gIcon(_folderIndex) )
  2038. err = fn GetIconRef( _kOnSystemDisk, _kSystemIconsCreator, _kGenericDocumentIcon, gIcon(_documentIndex) )
  2039. err = fn GetIconRef( _kOnSystemDisk, _kSystemIconsCreator, _kAliasBadgeIcon     , aliasBadgeIcon )
  2040.  
  2041. err = fn CompositeIconRef( gIcon(_folderIndex), aliasBadgeIcon, gIcon(_folderAliasIndex) )
  2042. if aliasBadgeIcon then err = fn ReleaseIconRef( aliasBadgeIcon )
  2043.  
  2044. // setting unique values for the DataBrowser columns
  2045. gCols(0)  = _checkboxColumnID
  2046. gCols(1)  = _flavorColumnID
  2047. gCols(2)  = _iconOnlyColumnID
  2048. gCols(3)  = _indexColumnID
  2049. gCols(4)  = _colorColumnID
  2050. gCols(5)  = _itemIDColumnID
  2051. gCols(6)  = _sliderColumnID
  2052. gCols(7)  = _progressColumnID
  2053. gCols(8)  = _dateTimeColumnID
  2054. gCols(9)  = _popupMenuColumnID
  2055.  
  2056. end fn
  2057.  
  2058. '~';
  2059. /*
  2060.      Cleaning up memory when the application ends.
  2061. */
  2062. local fn CleanupGlobals
  2063.  
  2064. dim as UInt32   i
  2065. dim as OSStatus err
  2066.  
  2067. long if gContextualMenu
  2068. DeleteMenu( _contextualMenuResID )
  2069. DisposeMenu( gContextualMenu )
  2070. end if
  2071.  
  2072. for i = 0 to _totalNumIcons - 1
  2073. if gIcon(i) then err = fn ReleaseIconRef( gIcon(i) )
  2074. next
  2075.  
  2076. end fn
  2077.  
  2078. '~';
  2079. /*
  2080.      The callback routines are redirected to local functions.
  2081.      In fact, the functions called are prototypes. The function
  2082.      below sets the vectors for all the prototype functions.
  2083. */
  2084. clear local fn SetupMyVectors
  2085.  
  2086. gDialogEventHandlerProc   = @fn MyDialogEventHandler
  2087. gWindowEventHandlerProc   = @fn MyWindowEventHandler
  2088.  
  2089. gPlacardDrawProc          = @fn MyPlacardDraw
  2090.  
  2091. gAcceptDragProc           = @fn MyAcceptDrag
  2092. gReceiveDragProc          = @fn MyReceiveDrag
  2093. gAddDragItemProc          = @fn MyAddDragItem
  2094. gGetSetItemDataProc       = @fn MyGetSetItemData
  2095. gItemComparisonProc       = @fn MyItemComparison
  2096. gItemNotificationProc     = @fn MyItemNotification
  2097. gItemHelpContentProc      = @fn MyItemHelpContent
  2098. gGetContextualMenuProc    = @fn MyGetContextualMenu
  2099. gSelectContextualMenuProc = @fn MySelectContextualMenu
  2100.  
  2101. end fn
  2102.  
  2103. '~Main Program
  2104. /*
  2105.      The main is just a function without event loop since the
  2106.      program uses Carbon Events.
  2107.      It creates a window and a DataBrowser, configure it and
  2108.      show the result on screen.
  2109. */
  2110. clear local fn main
  2111.  
  2112. dim as OSStatus        err
  2113. dim as Rect            r
  2114. dim as WindowRef     @ w
  2115. dim as ControlRef    @ browser, rootControl
  2116. dim as EventTypeSpec   wEvnt(6)
  2117.  
  2118. SetRect( r, 200, 200, 600, 400 )
  2119.  
  2120. // the events accepted by the main window
  2121. wEvnt.eventClass(0) = _kEventClassCommand
  2122. wEvnt.eventKind (0) = _kEventCommandProcess
  2123.  
  2124. wEvnt.eventClass(1) = _kEventClassCommand
  2125. wEvnt.eventKind (1) = _kEventCommandUpdateStatus
  2126.  
  2127. wEvnt.eventClass(2) = _kEventClassWindow
  2128. wEvnt.eventKind (2) = _kEventWindowClose
  2129.  
  2130. wEvnt.eventClass(3) = _kEventClassWindow
  2131. wEvnt.eventKind (3) = _kEventWindowGetIdealSize
  2132.  
  2133. wEvnt.eventClass(4) = _kEventClassWindow
  2134. wEvnt.eventKind (4) = _kEventWindowBoundsChanged
  2135.  
  2136. wEvnt.eventClass(5) = _kEventClassWindow
  2137. wEvnt.eventKind (5) = _kEventWindowGetClickActivation
  2138.  
  2139. wEvnt.eventClass(6) = _kEventClassWindow
  2140. wEvnt.eventKind (6) = _kEventWindowContextualMenuSelect
  2141.  
  2142.  
  2143. // Setup a few global variables
  2144. fn SetupGlobals
  2145. // Setup global vectors for the callback routines
  2146. fn SetupMyVectors
  2147. // Setup menubar
  2148. err = fn InstallStandardMenuBar( _true )
  2149. // Setup a window
  2150. long if fn CreateNewWindow(                                                    _kDocumentWindowClass, ┬
  2151. _kWindowInWindowMenuAttribute _kWindowStandardHandlerAttribute _kWindowStandardDocumentAttributes, ┬
  2152.                                                                                                 r, ┬
  2153.                                                                                                 w )
  2154. exit fn
  2155. end if
  2156.  
  2157. err = fn CreateRootControl( w, rootControl )
  2158. err = fn SetAutomaticControlDragTrackingEnabledForWindow( w, _true )
  2159.  
  2160. long if fn InstallWindowEventHandler(                                              w, ┬
  2161. fn NewEventHandlerUPP( [proc "WindowEventHandlerProc" + _FBprocToProcPtrOffset] ), ┬
  2162.                                                                                 7, ┬
  2163.                                                                         @wEvnt(0), ┬
  2164.                                                                             #_nil, ┬
  2165.                                                                             #_nil )
  2166. exit fn
  2167. end if
  2168. err = fn SetWindowTitleWithCFString( w, fn CFSTR("DataBrowser Demo") )
  2169.  
  2170. // Create the DataBrowser and install the callback routines
  2171. browser = fn CreateDataBrowser( w )
  2172. fn InstallDataBrowserCallbacks( browser )
  2173.  
  2174. // Configure the DataBrowser
  2175. fn ConfigureDataBrowser( browser )
  2176. err = fn SetDataBrowserTarget( browser, 50 )
  2177.  
  2178. // Set the keyboard focus
  2179. err = fn SetKeyboardFocus( w, browser, _kControlDataBrowserPart )
  2180.  
  2181. // Store our custom DataBrowser ID as a window property
  2182. err = fn SetWindowProperty( w, _myCreator, _myDataBrowser, sizeof(browser), browser )
  2183.  
  2184. // Show window & run
  2185. ShowWindow( w )
  2186. RunApplicationEventLoop
  2187. fn CleanupGlobals
  2188.  
  2189. end fn = err
  2190.  
  2191. '~';
  2192. // the program starts here calling the main function
  2193. fn Main
  2194.  
  2195. end
  2196.  
  2197. '~---
  2198. '~Applications Procs
  2199. /*
  2200.      Entry points for the callback procedures
  2201. */
  2202. #if def _FBUseDebugger
  2203. troff
  2204. #endif
  2205.  
  2206. goto "skip procs"
  2207.  
  2208. '~';
  2209.  
  2210. "AcceptDragProc"
  2211. enterproc fn AcceptDragProc( browser as ControlRef, theDrag as DragReference, itemID as DataBrowserItemID ) = Boolean
  2212. exitproc = fn Proto_AcceptDrag( browser, theDrag, itemID )
  2213.  
  2214. '~';
  2215.  
  2216. "ReceiveDragProc"
  2217. enterproc fn ReceiveDragProc( browser as ControlRef, theDrag as DragReference, itemID as DataBrowserItemID ) = boolean
  2218. exitproc = fn Proto_ReceiveDrag( browser, theDrag, itemID )
  2219.  
  2220. '~';
  2221.  
  2222. "AddDragItemProc"
  2223. enterproc fn AddDragItemProc( browser as ControlRef, theDrag as DragReference, inItemID as DataBrowserItemID, itemRef as .ItemReference ) = Boolean
  2224. exitproc = fn Proto_AddDragItem( browser , theDrag, inItemID, itemRef )
  2225.  
  2226. '~';
  2227.  
  2228. "GetSetItemDataProc"
  2229. enterproc fn GetSetItemDataProc( browser as ControlRef, itemID as DataBrowserItemID, prop as DataBrowserPropertyID, itemData as DataBrowserItemDataRef, changeValue as Boolean ) = OSStatus
  2230. exitproc = fn Proto_GetSetItemData( browser, itemID, prop, itemData, changeValue )
  2231.  
  2232. '~';
  2233.  
  2234. "ItemComparisonProc"
  2235. enterproc fn ItemComparisonProc( browser as ControlRef, itemOneID as DataBrowserItemID, itemTwoID as DataBrowserItemID, sortProperty as DataBrowserPropertyID ) = Boolean
  2236. exitproc = fn Proto_ItemComparison( browser, itemOneID, itemTwoID, sortProperty )
  2237.  
  2238. '~';
  2239.  
  2240. "ItemNotificationProc"
  2241. enterproc ItemNotificationProc( browser as ControlRef, itemID as DataBrowserItemID, message as DataBrowserItemNotification )
  2242. fn Proto_ItemNotification( browser, itemID, message )
  2243. exitproc
  2244.  
  2245. '~';
  2246.  
  2247. "ItemHelpContentProc"
  2248. enterproc ItemHelpContentProc( browser as ControlRef, item as DataBrowserItemID, prop as DataBrowserPropertyID, inRequest as HMContentRequest, outContentProvided as .HMContentProvidedType, ioHelpContent as .HMHelpContentRec )
  2249. fn Proto_ItemHelpContent( browser, item, prop, inRequest, outContentProvided, ioHelpContent )
  2250. exitproc
  2251.  
  2252. '~';
  2253.  
  2254. "GetContextualMenuProc"
  2255. enterproc GetContextualMenuProc( browser as ControlRef, @contextualMenu as .MenuRef, helpType as .UInt32, @helpItemString as .CFStringRef, selection as .AEDesc )
  2256. fn Proto_ContextualMenu( browser, contextualMenu, helpType, helpItemString, selection )
  2257. exitproc
  2258.  
  2259. '~';
  2260.  
  2261. "SelectContextualMenuProc"
  2262. enterproc SelectContextualMenuProc( browser as ControlRef, contextualMenu as MenuRef, selectionType as UInt32, menuID as SInt16, menuItem as MenuItemIndex )
  2263. fn Proto_SelectContextualMenu( browser, contextualMenu, selectionType, menuID, menuItem )
  2264. exitproc
  2265.  
  2266. '~';
  2267.  
  2268. "PlacardDrawProc"
  2269. enterproc PlacardDrawProc( c as ControlRef, dummy as SInt16 )
  2270. fn Proto_PlacardDraw( c, dummy )
  2271. exitproc
  2272.  
  2273. '~';
  2274.  
  2275. "DialogEventHandlerProc"
  2276. enterproc fn DialogEventHandlerProc( EventHandlerCallRef as ptr, inEvent as EventRef, void as ptr ) = OSStatus
  2277. exitproc = fn Proto_DialogEventHandler( EventHandlerCallRef, inEvent, void )
  2278.  
  2279. '~';
  2280.  
  2281. "WindowEventHandlerProc"
  2282. enterproc fn WindowEventHandlerProc( EventHandlerCallRef as ptr, inEvent as EventRef, void as ptr ) = OSStatus
  2283. exitproc = fn Proto_WindowEventHandler( EventHandlerCallRef, inEvent, void )
  2284.  
  2285.  
  2286. "skip procs"
  2287.  
  2288. #if def _FBUseDebugger
  2289. tron
  2290. #endif
  2291.  
  2292.